Some new methods of Map interface in Java

getOrDefault method

This is easy to understand. If it get(key)is empty, it will return the default value, otherwise it will return directly.

default V getOrDefault(Object key, V defaultValue) {
    
    
        V v;
        return (((v = get(key)) != null) || containsKey(key))
            ? v
            : defaultValue;
    }

putIfAbsent method

This is easy to understand. If the current key corresponds to an empty value, put it. Otherwise, do nothing.

	default V putIfAbsent(K key, V value) {
    
    
        V v = get(key);
        if (v == null) {
    
    
            v = put(key, value);
        }
        return v;
    }

merge method

This method is passed key, value, if oldValueempty, then to the Senate valueon directly assigned newValue, or to perform calculations lambda expressions, if the calculated result is empty, on the implementation of the delete key.

default V merge(K key, V value,
            BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    
    
        Objects.requireNonNull(remappingFunction);
        Objects.requireNonNull(value);
        V oldValue = get(key);
        V newValue = (oldValue == null) ? value :
                   remappingFunction.apply(oldValue, value);
        if (newValue == null) {
    
    
            remove(key);
        } else {
    
    
            put(key, newValue);
        }
        return newValue;
    }

compute method

Look at the code directly

	default V compute(K key,
            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    
    
        Objects.requireNonNull(remappingFunction);
        V oldValue = get(key);
        //通过传入的函数式接口计算出新value
        V newValue = remappingFunction.apply(key, oldValue);
        //如果新value为空,否则什么也不做。
        if (newValue == null) {
    
    
            // 旧value不为空,或者map中存在当前key就删除(这个是考虑key对应的oldValue就是null)
            if (oldValue != null || containsKey(key)) {
    
    
                remove(key);
                return null;
            } else {
    
    //否则什么也不做
                return null;
            }
        } else {
    
    
            //如果新value不为空,就相当于普通的put方法
            put(key, newValue);
            return newValue;
        }
    }

So the compute method is to give it a key and lambda expression (functional interface Function should be known, BiFunction is a Function interface with two parameters), if the result of this lambda expression is null, delete the map, otherwise Just perform ordinary put.

So merge and compute the difference is in the method 入参, lambda表达式and the remove(key)difference when.

  • Merge can manually set an input parameter value to facilitate external settings. The parameters of the lambda expression areEnter val and oldVal. It remove(key)will not check if it exists in the map key.
  • The compute input has no value. The parameters of the lambda expression arekey and oldVal. At the remove(key)time, it will check whether the key exists in the map, and if it does not exist, it will not delete it. But the return of compute is really ugly. . Just write return at the end just like merge. .

For example, to count the number of occurrences of each element.

public static void main(String[] args) throws IOException {
    
    
    Map<Integer, Integer> map = new HashMap<>();
    int[] nums = {
    
    1, 2, 3, 1, 42, 32, 33, 131, 131, 2, 3, 3, 3, 1, 3, 42};
    //如果你不知道getOrDefault就可能会这样做
    for (int num : nums) {
    
    
      Integer cnt = map.get(num);
      if (cnt == null) map.put(num, 1);
      else map.put(num, cnt + 1);
    }
    //如果你知道可能会这样做
    for (int num : nums) {
    
    
      map.put(num, map.getOrDefault(num, 0) + 1);
    }
    //如果你知道merge,可以这样
    for (int num : nums) {
    
    
      map.merge(num, 1, (old, val) -> old + val);
    }
    //如果你知道compute,那还可以这样做。
    //这里看着比上面还长,但是如果在计算新value的时候如果需要同时用到
    //oldValue和key那么这个方法就可以省去一些判断
    for (int num : nums) {
    
    
      map.compute(num, (key, old) -> old == null ? 1 : old + 1);
    }
  }

computeIfAbsent method

This method is easy to understand by looking at the name. If the value corresponding to the key is null, the operation is performed, otherwise it does nothing.
But it is different from the compute method. When calculating the new value, the parameter is only the key, which is the key passed in.

	default V computeIfAbsent(K key,
            Function<? super K, ? extends V> mappingFunction) {
    
    
        Objects.requireNonNull(mappingFunction);
        V v;
        if ((v = get(key)) == null) {
    
    
            V newValue;
            //通过key计算出新value,并且新value不为null时才进行put
            if ((newValue = mappingFunction.apply(key)) != null) {
    
    
                put(key, newValue);
                return newValue;
            }
        }
        return v;
    }

computeIfPresent method

Contrary to the above, if the value obtained by the passed key is not empty, the operation is performed, otherwise nothing is done.
Like the compute method, there are two parameters when calculating the new value, namely the passed key and oldValue.

	default V computeIfPresent(K key,
            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    
    
        Objects.requireNonNull(remappingFunction);
        V oldValue;
        if ((oldValue = get(key)) != null) {
    
    
            V newValue = remappingFunction.apply(key, oldValue);
            //如果新value
            if (newValue != null) {
    
    
                put(key, newValue);
                return newValue;
            } else {
    
    
                remove(key);
                return null;
            }
        } else {
    
    
            return null;
        }
    }

replace method

If the value corresponding to the key is the same as oldValue, replace it with newValue, otherwise nothing will be done.

default boolean replace(K key, V oldValue, V newValue) {
    
    
        Object curValue = get(key);
        if (!Objects.equals(curValue, oldValue) ||
            (curValue == null && !containsKey(key))) {
    
    
            return false;
        }
        put(key, newValue);
        return true;
    }

Guess you like

Origin blog.csdn.net/qq_42007742/article/details/109038858