返回

直击Hashmap内核,以探寻其秘密!

Android

一、HashMap的结构

HashMap本质上是一个数组,数组中的每个元素都是一个链表。数组的长度是固定的,链表的长度是可变的。当向HashMap中插入一个元素时,先计算出该元素的HashCode,然后用HashCode与数组的长度进行求余,得到一个索引,将元素插入到对应的链表中。

二、HashMap的查找

当在HashMap中查找一个元素时,同样需要计算出该元素的HashCode,然后用HashCode与数组的长度进行求余,得到一个索引,在对应的链表中查找该元素。如果链表中存在该元素,则返回该元素的值;如果链表中不存在该元素,则返回null。

三、HashMap的插入

当向HashMap中插入一个元素时,首先需要计算出该元素的HashCode,然后用HashCode与数组的长度进行求余,得到一个索引,在对应的链表中查找该元素。如果链表中存在该元素,则更新该元素的值;如果链表中不存在该元素,则创建一个新的节点,并将该元素插入到链表中。

四、HashMap的删除

当从HashMap中删除一个元素时,首先需要计算出该元素的HashCode,然后用HashCode与数组的长度进行求余,得到一个索引,在对应的链表中查找该元素。如果链表中存在该元素,则将其从链表中删除;如果链表中不存在该元素,则什么都不做。

五、HashMap的效率

HashMap的查找、插入和删除的时间复杂度都是O(1),这是因为HashMap的数组长度是固定的,查找、插入和删除元素时只需要遍历数组中的一个链表,而链表的长度是可变的。

六、HashMap的应用

HashMap在Java中有着广泛的应用,它可以用于实现各种数据结构,如Set、Map、List等。HashMap也常用于缓存数据,因为它的查找速度很快。

七、HashMap的代码实现

以下是HashMap的Java代码实现:

public class HashMap<K, V> {

    private Node<K, V>[] table;

    private int size;

    public HashMap() {
        table = new Node[16];
    }

    public void put(K key, V value) {
        int index = key.hashCode() % table.length;
        Node<K, V> node = table[index];
        while (node != null) {
            if (node.key.equals(key)) {
                node.value = value;
                return;
            }
            node = node.next;
        }
        Node<K, V> newNode = new Node<>(key, value);
        newNode.next = table[index];
        table[index] = newNode;
        size++;
    }

    public V get(K key) {
        int index = key.hashCode() % table.length;
        Node<K, V> node = table[index];
        while (node != null) {
            if (node.key.equals(key)) {
                return node.value;
            }
            node = node.next;
        }
        return null;
    }

    public void remove(K key) {
        int index = key.hashCode() % table.length;
        Node<K, V> node = table[index];
        Node<K, V> prev = null;
        while (node != null) {
            if (node.key.equals(key)) {
                if (prev == null) {
                    table[index] = node.next;
                } else {
                    prev.next = node.next;
                }
                size--;
                return;
            }
            prev = node;
            node = node.next;
        }
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    private static class Node<K, V> {

        private K key;

        private V value;

        private Node<K, V> next;

        public Node(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }
}