private static void testGetOrDefault() { Map<String, String> map = new HashMap<>(4); map.put('123', '123'); String key = 'key'; String defaultValue = 'defaultValue'; // 老写法 String oldValue = defaultValue; if (map.containsKey(key)) { oldValue = map.get(key); } System.out.println('oldValue = ' + oldValue); // 堆代码 duidaima.com // 新写法 String newValue = map.getOrDefault(key, defaultValue); System.out.println('newValue = ' + newValue); }foreach
private static void testForeach() { Map<String, String> map = new HashMap<>(4); map.put('123', '123'); // 老写法 for (Map.Entry<String, String> entry : map.entrySet()) { System.out.printf('老写法 key = %s, value = %s%n', entry.getKey(), entry.getValue()); } // 新写法 map.forEach((key, value) -> System.out.printf('新写法 key = %s, value = %s%n', key, value)); }merge
@Override public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { if (value == null || remappingFunction == null) throw new NullPointerException(); int hash = hash(key); Node<K,V>[] tab; Node<K,V> first; int n, i; int binCount = 0; TreeNode<K,V> t = null; Node<K,V> old = null; if (size > threshold || (tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((first = tab[i = (n - 1) & hash]) != null) { if (first instanceof TreeNode) old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key); else { Node<K,V> e = first; K k; do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) { old = e; break; } ++binCount; } while ((e = e.next) != null); } } if (old != null) { V v; if (old.value != null) { int mc = modCount; v = remappingFunction.apply(old.value, value); if (mc != modCount) { throw new ConcurrentModificationException(); } } else { v = value; } if (v != null) { old.value = v; afterNodeAccess(old); } else removeNode(hash, key, null, false, true); return v; } else { if (t != null) t.putTreeVal(this, tab, hash, key, value); else { tab[i] = newNode(hash, key, value, first); if (binCount >= TREEIFY_THRESHOLD - 1) treeifyBin(tab, hash); } ++modCount; ++size; afterNodeInsertion(true); return value; } }代码比较长,但是实现的效果比较容易描述:这个方法接收3个参数:key、value、function。
如果key存在,将value按照function做1次计算后,更新到Map中,如果key不存在,将key-value放入Map中。
private static void testMerge() { Map<String, Integer> cntMap = new HashMap<>(8); List<String> list = Arrays.asList('apple', 'orange', 'banana', 'orange'); // 老写法 for (String item : list) { if (cntMap.containsKey(item)) { cntMap.put(item, cntMap.get(item) + 1); } else { cntMap.put(item, 1); } } // 新写法 for (String item : list) { cntMap.merge(item, 1, Integer::sum); } }
可以看到我们使用merge方法的话,只用1行就简洁实现了这个逻辑。
private static void testPutIfAbsent() { Map<String, Integer> scoreMap = new HashMap<>(4); scoreMap.put('Jim', 88); scoreMap.put('Lily', 90); // 老写法 if (!scoreMap.containsKey('Lily')) { scoreMap.put('Lily', 98); } // 新写法 scoreMap.putIfAbsent('Lily', 98); }computer
private static void testComputer() { Map<String, Integer> cntMap = new HashMap<>(8); List<String> list = Arrays.asList('apple', 'orange', 'banana', 'orange'); // 老写法 for (String item : list) { if (cntMap.containsKey(item)) { cntMap.put(item, cntMap.get(item) + 1); } else { cntMap.put(item, 1); } } // 新写法 for (String item : list) { cntMap.compute(item, (k, v) -> { if (v == null) { v = 1; } else { v += 1; } return v; }); } }computeIfAbsent
private static void testComputerIfAbsent() { Map<Integer, Integer> fabMap = new ConcurrentHashMap<>(16); fabMap.put(0, 1); fabMap.put(1, 1); System.out.println(fab(5, fabMap)); } private static Integer fab(Integer index, Map<Integer, Integer> fabMap) { return fabMap.computeIfAbsent(index, i -> fab(i - 2, fabMap) + fab(i - 1, fabMap)); }computeIfPresent