Java 8 HashMap
HashMap 使用数组、链表和红黑树存储键值对,当链表足够长时,会转换为红黑树。HashMap 是非线程安全的。 HashMap 中的常量static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; static final int MAXIMUM_CAPACITY = 1 << 30; static final float DEFAULT_LOAD_FACTOR = 0.75f; static final int TREEIFY_THRESHOLD = 8; static final int UNTREEIFY_THRESHOLD = 6; static final int MIN_TREEIFY_CAPACITY = 64;
使用有参构造方法可以指定初始容量和装填因子,指定的容量会被向上调整为 2 的 n 次幂(比如给定容量为13,则会调整为 16)。 HashMap 中键值对的值可以为 null,可以存在一个 key 为 null 的键值对。 HashMap 的部分方法treeifyBin 方法/** * Replaces all linked nodes in bin at index for given hash unless * table is too small,in which case resizes instead. */ final void treeifyBin(Node<K,V>[] tab,int hash) { int n,index; Node<K,V> e; // 判断是否达到转化为树的阈值 if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY) resize(); // 没有达到只做扩容操作 else if ((e = tab[index = (n - 1) & hash]) != null) { TreeNode<K,V> hd = null,tl = null; do { TreeNode<K,V> p = replacementTreeNode(e,null); if (tl == null) hd = p; else { p.prev = tl; tl.next = p; } tl = p; } while ((e = e.next) != null); if ((tab[index] = hd) != null) hd.treeify(tab); } } 在调用 这里的 (n - 1) & hash 就是求余操作,相当于 hash % n,因为 HashMap 的长度总是 2 的 n 次幂。 replaceAll 方法@Override public void replaceAll(BiFunction<? super K,? super V,? extends V> function) { Node<K,V>[] tab; if (function == null) throw new NullPointerException(); if (size > 0 && (tab = table) != null) { int mc = modCount; for (int i = 0; i < tab.length; ++i) { for (Node<K,V> e = tab[i]; e != null; e = e.next) { e.value = function.apply(e.key,e.value); } } if (modCount != mc) throw new ConcurrentModificationException(); } } 该方法接受一个 lambda 表达式,将满足给定条件的值替换掉,比如: HashMap<Integer,String> map = ...; // 将 key 为偶数的所有键值对的值替换为 "foo" map.replaceAll((k,v) -> k % 2 == 0 ? "foo" : v); forEach 方法@Override public void forEach(BiConsumer<? super K,? super V> action) { Node<K,V>[] tab; if (action == null) throw new NullPointerException(); if (size > 0 && (tab = table) != null) { int mc = modCount; for (int i = 0; i < tab.length; ++i) { for (Node<K,V> e = tab[i]; e != null; e = e.next) action.accept(e.key,e.value); } if (modCount != mc) throw new ConcurrentModificationException(); } } 该方法也接受一个 lambda 表达式,用于消费键值对: // 打印所有键值对 map.forEach( (k,v) -> System.out.println(k + ": " + v) ); // 打印所有 key 为偶数的键值对 map.forEach( (k,v) -> { if (k % 2 == 0) System.out.println(k + ": " + v) } ); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |