New methods in Map

Map has more methods than Collection!

forEach()

Void forEach(BiConsumer<? super K,? Super V> action), where BiConsumer is a function interface with a method to implement void accept(T T, U U).

Neither the BinConsumer interface name nor the Accept () method name is important, so please don’t remember them.

Requirement: If there is a Map of a number to an English word, output all the mappings in the Map. Java7 and the classic code before it looks like this:

// Java7 and previous iterations of Map HashMap<Integer, String> Map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for(Map.Entry<Integer, String> entry : map.entrySet()){ System.out.println(entry.getKey() + "=" + entry.getValue()); }Copy the code

Using the map.foreach () method, combined with the anonymous inner class, the code looks like this:

// Use forEach() to iterate over Map HashMap<Integer, String> Map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.forEach(new BiConsumer<Integer, String>(){ @Override public void accept(Integer k, String v){ System.out.println(k + "=" + v); }});Copy the code

The above code calls the forEach() method and implements the BiConsumer interface with an anonymous inner class.

Of course, no one uses anonymous inner class writing in the real world because of Lambda expressions:

HashMap<Integer, String> Map = new HashMap<>(); // Use forEach() to iterate over the Map with a Lambda expression. map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.forEach((k, v) -> System.out.println(k + "=" + v)); }Copy the code

getOrDefault()

This method has nothing to do with Lambda expressions, but it’s useful.

The method is signed by V getOrDefault(Object key, V defaultValue). It is used to query the corresponding value in the Map according to the given key. If no value is found, the defaultValue is returned.

Using this method saves the programmer the trouble of querying whether a specified key value exists.

Demand; If a number is added to the Map of the corresponding English word, output the English word corresponding to 4, or output NoValue if none exists

HashMap<Integer, String> Map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); If (map.containskey (4)){// 1 system.out.println (map.get(4)); }else{ System.out.println("NoValue"); } // Java8 uses map.getorDefault () system.out.println (map.getorDefault (4, "NoValue")); // Java8 uses map.getorDefault () system.out.println (map.getorDefault (4, "NoValue")); / / 2Copy the code

The putIfAbsent() method has nothing to do with Lambda expressions, but is useful.

The method signature is V putIfAbsent(K key, V value). The value specified by value is added to the Map only when there is no key mapping or the mapping value is null. Otherwise, the Map is not changed.

This method combines conditional judgment and assignment, which makes it more convenient to use.

remove()

We all know that Map has a remove(Object key) method that removes the mapping based on the specified key value. Java8 added the remove(Object key, Object value) method, which removes the mapping only if the key in the current Map is exactly mapped to the value, otherwise nothing is done.

replace()

In Java7 and before, replacing a mapping in a Map was done with the put(K key, V value) method, which always replaced the original value with a new value.

For more precise control of the replace behavior, Java8 adds two replace() methods to the Map, as follows:

  • Replace (K key, V value), use value to replace the original value only if the key mapping exists in the current Map, otherwise do nothing.

  • Replace (K key, V oldValue, V newValue), replace(K key, V oldValue, V newValue), replace(K key, V oldValue, V newValue), replace(K key, V oldValue, V newValue), replace(K key, V oldValue, V newValue), replace(K key, V oldValue, V newValue), replace(K key, V oldValue, V newValue).

ReplaceAll () This method is signed as replaceAll(BiFunction<? super K,? super V,? Extends V> function); extends V> function); extends V> function); extends V> function); extends V> function); There’s a method to be implemented, R apply(T, T, U, U).

Don’t be intimidated by the number of function interfaces, because you don’t need to know their names to use them.

Requirement: Assuming there is a Map of a number to an English word, convert the words in the original mapping relationship to uppercase. Java7 and the classic code before it looks like this:

HashMap<Integer, String> Map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for(Map.Entry<Integer, String> entry : map.entrySet()){ entry.setValue(entry.getValue().toUpperCase()); }Copy the code

Using the replaceAll() method in combination with an anonymous inner class, the implementation is as follows:

// Use replaceAll() to implement HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.replaceAll(new BiFunction<Integer, String, String>(){ @Override public String apply(Integer k, String v){ return v.toUpperCase(); }});Copy the code

The above code calls the replaceAll() method and implements the BiFunction interface using an anonymous inner class.

Further, a Lambda expression is used to implement the following:

HashMap<Integer, String> map = new HashMap<>(); // Use replaceAll() to implement HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.replaceAll((k, v) -> v.toUpperCase());Copy the code

It’s incredibly brief.

merge()

Merge (K key, V value, BiFunction<? super V,? super V,? Extends V> remappingFunction extends V> remappingFunction

  • If the Map corresponding to the key does not exist or is null, then value (which cannot be null) is associated with the key.

  • Otherwise, remappingFunction is executed. If the result is not null, the result is associated with the key. Otherwise, the key mapping is deleted from the Map.

The BiFunction function interface has been introduced before, and there is a method to implement R apply(T T, U U).

The merge() method is a bit more complex, but it’s pretty clear how to use it. A common scenario is to merge a new error message onto the original one. For example:

map.merge(key, newMsg, (v1, v2) -> v1+v2);
Copy the code

compute()

Compute (K key, BiFunction<? super K,? super V,? Extends V> remappingFunction) extends V> remappingFunction) to associate the result of a remappingFunction calculation to a key. If the result is null, then delete the key mapping from the Map.

To implement the example of merge() error information concatenation, use the following compute() code:

map.compute(key, (k,v) -> v==null ? newMsg : v.concat(newMsg));
Copy the code

computeIfAbsent()

V computeIfAbsent(K key, Function<? super K,? Extends V> mappingFunction extends V> mappingFunction MappingFunction is called only when there is no key mapping or the mapping value is null in the current Map. If the result of mappingFunction execution is not null, the result is associated with the key.

Function is a Function interface with a method R apply(T T) to be implemented.

ComputeIfAbsent () is used to set up an initial Map for a key value of the Map. For example, if we want to implement a multi-valued Map, the Map definition might be Map<K,Set>. To add new values to the Map, we can implement the following code:

Map<Integer, Set<String>> map = new HashMap<>(); If (map.containskey (1)){map.get(1).add("one"); }else{ Set<String> valueSet = new HashSet<String>(); valueSet.add("one"); map.put(1, valueSet); Map.com puteIfAbsent(1, v -> new HashSet<String>()).add("yi");Copy the code

Use computeIfAbsent() to combine the conditional and add operations to make the code even cleaner.

computeIfPresent()

V computeIfPresent(K key, BiFunction<? super K,? super V,? Extends V> remappingFunction); extends V> remappingFunction); extends V> remappingFunction); extends V> remappingFunction); extends V> remappingFunction); If the result of remappingFunction is NULL, the key mapping is deleted; otherwise, the result is used to replace the original key mapping.

This function is equivalent to the following code:

// Java7 and previous computeIfPresent() equivalent if (map.get(key)! = null) { V oldValue = map.get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue ! = null) map.put(key, newValue); else map.remove(key); return newValue; } return null;Copy the code