HashCode

HashCode

就是给数组设定一个容量,不同的哈希码%这个容量,取得序号,放到数组里。

如果发现有重复了,通过链表的形式,增加一个元素。


对于HashMap,键是不允许重复的。

如果可以重复的话,可以用两个ArrayList打造出来。

如果不允许重复,就是需要进行一个比较。

然而equals的比较效率太低,HashCode会很高,原理如上所述。

只需要在发现重复的时候(别人称之为碰撞),进行equals的比较即可。


Thinking In Java中给的伪代码,这里不愿花费时间去注释了,见谅。

public class SimpleHashMap<K,V> extends AbstractMap<K,V>{
    private static final int SIZE = 997;

    @SuppressWarnings("unchecked")
    private LinkedList<MapEntry<K,V>>[] buckets = new LinkedList[SIZE];

    public V put(K key, V value) {
        V oldValue = null;
        int index = Math.abs(key.hashCode()) % SIZE;
        if (buckets[index] == null)
            buckets[index] = new LinkedList<>();
        LinkedList<MapEntry<K,V>> bucket = buckets[index];
        MapEntry<K,V> pair = new MapEntry<>(key, value);
        boolean found = false;
        ListIterator<MapEntry<K,V>> it = bucket.listIterator();
        while (it.hasNext()) {
            MapEntry<K,V> iPair = it.next();
            if (iPair.getKey().equals(key)) {
                oldValue = iPair.getValue();
                it.set(pair);
                found = true;
                break;
            }
        }
        if (!found)
            buckets[index].add(pair);
        return oldValue;
    }

    public V get(Object key) {
        int index = Math.abs(key.hashCode()) % SIZE;
        if (buckets[index] == null)
            return null;
        for (MapEntry<K,V> iPair : buckets[index])
            if (iPair.getKey().equals(key))
                return iPair.getValue();
        return null;
    }

    public Set<Map.Entry<K,V>> entrySet() {
        Set<Map.Entry<K,V>> set = new HashSet<>();
        for (LinkedList<MapEntry<K,V>> bucket : buckets) {
            if (bucket == null) continue;
            set.addAll(bucket);
        }
        return set;
    }

    public static void main(String[] args) {
        SimpleHashMap<String,String> m = new SimpleHashMap<>();
    }

    static class MapEntry<K,V> implements Map.Entry<K,V> {
        private K key;
        private V value;
        MapEntry(K key, V value) {
            this.key = key;
            this.value = value;
        }
        public K getKey() {return key;}
        public V getValue() {return value;}
        public V setValue(V v) {
            V result = value;
            value = v;
            return result;
        }
        public int hashCode() {
            return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
        }
        public boolean equals(Object o) {
            if (!(o instanceof MapEntry)) return false;
            MapEntry me = (MapEntry) o;
            return (key == null ? me.getKey() == null : key.equals(me.getKey())) && (value == null ? me.getValue() == null : value.equals(me.getValue()));
        }
        public  String toString() {return key + "=" + value;}
    }
}

(此外HashCode最优函数,在Thinking In Java中)


仅仅是这样,并没有实现HashMap的性能调优,需要先看一下红黑树,再进行HashMap的源码的阅读才可以。