Android技术知识Android开发Android开发经验谈

数据结构----HashMap哈希表

2018-08-21  本文已影响17人  pgydbh

结构

数组。
需要size()----大小
需要put(k,v)----放入
需要get(i)----取出

思路

①初始化空间大小为2^n,比如2,4,8,16。
②从节点计算hash&(length-1)得到位置插入,之后计算是否超出阈值(这个阈值由自己决定,是否超出阈值决定了要不要扩容)

对于上面的解释
①hash值不确定,可能会特别大,加入长度为16,hash为11111111
②00001111&11111111=00001111=15
③所有的hash都在当前范围内,但会形成链。
④有人分析了很多得出结论----扩容2倍是最好的,避免了数组空间的浪费,充分利用了空间,减少了碰撞的概率。https://blog.csdn.net/jiary5201314/article/details/51439982
⑤但是个人觉得选择2倍扩容,并且初始为2的倍数,只是为了处理分配空间,扩容重新排序的正常反应。

③如果阈值大于自己的设定值(demo里设最长链长度为b,空间大小为2^n,当b>n)
④新建一个长度为当前二倍的数组空间,数据整理到新的数组中。hashmap的数组变更为新的数组。
⑤继续插入。

代码


public class HashMap<K, V> {

    private Node<K, V>[] nodes = new Node[2];
    private int len = 2;
    private int mi = 1;
    private int size;
    private int branch;

    public int size(){
        return size;
    }

    public void put(K k, V v){
        int temp = (len - 1) & k.hashCode();
        if (nodes[temp] == null){
            nodes[temp] = new Node<>(k, v);
        } else {
            Node node = nodes[temp];
            int i = 1;
            while (node != null){
                i++;
                if (node.k.equals(k)){
                    node.v = v;
                    size--;
                    break;
                }
                if (node.next == null){
                    node.next = new Node(k, v);
                    break;
                }
                node = node.next;
            }
            if (i > branch) {
                branch = i;
            }
        }
        size++;
        if (branch > mi && mi < 31){
            sort();
        }
    }

    //内部整理put
    private void put(Node[] nodes, K k, V v){
        int temp = (nodes.length - 1) & k.hashCode();
        if (nodes[temp] == null){
            nodes[temp] = new Node<>(k, v);
        } else {
            Node node = nodes[temp];
            while (node != null){
                if (node.k.equals(k)){
                    node.v = v;
                    size--;
                    break;
                }
                if (node.next == null){
                    node.next = new Node(k, v);
                    break;
                }
                node = node.next;
            }
        }
    }

    public V get(K k){
        int temp = k.hashCode() & (len - 1);
        if (temp < size && temp >= 0){
            Node node = nodes[temp];
            while (node != null) {
                if (node.k.equals(k)){
                    return (V) node.v;
                }
                node = node.next;
            }
        }
        return null;
    }

    private void sort(){
        Node<K, V>[] newNodes = new Node[len = len * 2];
        mi++;
        for (int i = 0; i < nodes.length; i++){
            if (nodes[i] != null){
                put(newNodes, nodes[i].k, nodes[i].v);
                Node<K, V> node = nodes[i].next;
                while (node != null){
                    put(newNodes, node.k, node.v);
                    node = node.next;
                }
            }
        }
        nodes = newNodes;
    }

    public static class Node<K, V>{
        public K k;
        public V v;
        public Node next;
        public Node(K k, V v){
            this.k = k;
            this.v = v;
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读