java8 Map新增方法的使用

x33g5p2x  于2022-01-13 转载在 Java  
字(9.5k)|赞(0)|评价(0)|浏览(456)

文章目录

java8 Map新增方法的使用

概述

java8 Map中新增了几个面向函数式编程的几个方法
利用java8可以在接口中定义default方法实现

1、compute()
1、使用
  1. Map<Integer, Integer> map = new HashMap<>(16);
  2. map.compute(1, (k, v) -> {
  3. if (v == null) {
  4. return 1;
  5. }
  6. return ++v;
  7. });

以上方法表示:如果key不存在就设置value为1;如果存在则value值+1并设置为value

2、源码实现
  1. default V compute(K key,
  2. BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
  3. Objects.requireNonNull(remappingFunction);
  4. V oldValue = get(key);
  5. // 传入的函数入参是key和旧的value值
  6. V newValue = remappingFunction.apply(key, oldValue);
  7. if (newValue == null) {
  8. // 如果函数返回的新值为null,将移除key
  9. if (oldValue != null || containsKey(key)) {
  10. // something to remove
  11. remove(key);
  12. return null;
  13. } else {
  14. // nothing to do. Leave things as they were.
  15. return null;
  16. }
  17. } else {
  18. // add or replace old mapping
  19. put(key, newValue);
  20. return newValue;
  21. }
  22. },

简单的来说就是将当前key的,key值和value值作为你的函数入参,根据个人定义的函数返回新的value值,若新的值为null则移除当前key,否则替换成新的值,并返回新值

2、computeIfAbsent()
1、使用
  1. map.computeIfAbsent(2, k -> 2*k);

表示key=2的值不存在,则设置2*k的值,如果key存在则不做任何修改

2、源码
  1. default V computeIfAbsent(K key,
  2. Function<? super K, ? extends V> mappingFunction) {
  3. Objects.requireNonNull(mappingFunction);
  4. V v;
  5. if ((v = get(key)) == null) {
  6. V newValue;
  7. if ((newValue = mappingFunction.apply(key)) != null) {
  8. put(key, newValue);
  9. return newValue;
  10. }
  11. }
  12. return v;
  13. }

这段代码看起来就非常简单 就是如果key存在则返回当前值;如果key不存在,获取函数返回值,若返回值不为null,则设置为当前key的值,否则不做任何操作返回当前key的值

3、computeIfPresent()

从命名上看就知道,当key值存在的时候,则会进行一些操作,直接贴源码

  1. default V computeIfPresent(K key,
  2. BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
  3. Objects.requireNonNull(remappingFunction);
  4. V oldValue;
  5. if ((oldValue = get(key)) != null) {
  6. V newValue = remappingFunction.apply(key, oldValue);
  7. if (newValue != null) {
  8. put(key, newValue);
  9. return newValue;
  10. } else {
  11. remove(key);
  12. return null;
  13. }
  14. } else {
  15. return null;
  16. }
  17. }

当key存在的时候,将不为null的新值替换旧值,否则移除key

4、merge()
1、使用
  1. Integer merge = map.merge(1, 2, (old, v) -> old + v);
2、源码
  1. default V merge(K key, V value,
  2. BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
  3. Objects.requireNonNull(remappingFunction);
  4. Objects.requireNonNull(value);
  5. V oldValue = get(key);
  6. V newValue = (oldValue == null) ? value :
  7. remappingFunction.apply(oldValue, value);
  8. if(newValue == null) {
  9. remove(key);
  10. } else {
  11. put(key, newValue);
  12. }
  13. return newValue;
  14. }

获取当前key的值,如果不存在则使用value作为新的值,否则使用旧值和入参的value作为函数的参数获取新的值,并替换当前值

5、接下来简单介绍一下1.8之后Map添加的default方法
  1. default V replace(K key, V value):key存在且value值不为null,则替换,并返回旧值
  2. default boolean replace(K key, V oldValue, V newValue):类似于CAS,如果key存在且value值不为null且value值等于预期的oldValue,则替换,否则返回false
  3. default boolean remove(Object key, Object value):当前key存在且其value值不为null并且入参value等于其当前值,则移除key 否则返回false
  4. default V putIfAbsent(K key, V value):如其名,key不存在或当前值为null,则给put,并返回旧值
  5. default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function):根据函数返回值,替换所有key的value值
  6. default void forEach(BiConsumer<? super K, ? super V> action):遍历
  7. default V getOrDefault(Object key, V defaultValue):key不存在或值为null,则返回默认值,否则返回当前值

map新增的方法:

  • getOrDefault
  • forEach
  • putIfAbsent
  • compute
  • computeIfAbsent
  • computeIfPresent
  • merge
  • remove(key,value)
  • replace
  • replaceAll

getOrDefault

  1. default V getOrDefault(Object key, V defaultValue) {
  2. V v;
  3. return (((v = get(key)) != null) || containsKey(key))
  4. ? v
  5. : defaultValue;
  6. }

如果Map中不存在该key,可以提供一个默认值,方法会返回改默认值。如果存在该key,返回键对应的值。

java8之前的写法:

  1. Map<String, String> map = new HashMap<>();
  2. String value = "D";
  3. if(map.containsKey("d")) {
  4. value = map.get("d");
  5. }

java8:

  1. String value = map.getOrDefault("d", "D");

forEach

  1. default void forEach(BiConsumer<? super K, ? super V> action) {
  2. Objects.requireNonNull(action);
  3. for (Map.Entry<K, V> entry : entrySet()) {
  4. K k;
  5. V v;
  6. try {
  7. k = entry.getKey();
  8. v = entry.getValue();
  9. } catch(IllegalStateException ise) {
  10. // this usually means the entry is no longer in the map.
  11. throw new ConcurrentModificationException(ise);
  12. }
  13. action.accept(k, v);
  14. }
  15. }

forEach遍历map,对map中的每个映射执行action指定的操作。
比如:

  1. Map<String, String> map = new HashMap<>();
  2. map.put("a", "A");
  3. map.put("b", "B");
  4. // 遍历
  5. map.forEach((k, v)-> {
  6. System.out.println(k + "=" + v);
  7. map.put(k, k + v);
  8. });
  9. // 输出
  10. // a=A
  11. // b=B
  12. map.forEach((k, v)-> {
  13. System.out.println(k + "=" + v);
  14. });
  15. // 输出
  16. // a=aA
  17. // b=bB

putIfAbsent

  1. default V putIfAbsent(K key, V value) {
  2. V v = get(key);
  3. if (v == null) {
  4. v = put(key, value);
  5. }
  6. return v;
  7. }

V putIfAbsent(K key, V value)只有在不存在key值的映射或者映射值为null,才将value值赋值给key。否则不做修改。该方法将条件判断和赋值合二为一。

比如:

  1. Map<String, String> map = new HashMap<>();
  2. map.put("a", "A");
  3. map.put("b", "B");
  4. String e = map.putIfAbsent("e", "E");
  5. String b = map.putIfAbsent("b", "E");
  6. System.out.println("返回e="+e); //返回e=null
  7. System.out.println("键e="+map.get("e"));//键e=E
  8. System.out.println("返回b="+b);//返回b=B
  9. System.out.println("键b="+map.get("b"));//键b=B

remove(key,value)

  1. default boolean remove(Object key, Object value) {
  2. Object curValue = get(key);
  3. if (!Objects.equals(curValue, value) ||
  4. (curValue == null && !containsKey(key))) {
  5. return false;
  6. }
  7. remove(key);
  8. return true;
  9. }

只有在当前Map中key映射的值等于value时才删除该映射,否则什么也不做。

  1. Map<String, String> map = new HashMap<>();
  2. map.put("a", "A");
  3. map.put("b", "B");
  4. map.remove("a", "B");
  5. map.remove("b", "B");
  6. System.out.println(map.get("a")); // A
  7. System.out.println(map.get("b")); // null

replace(K key, V value)

  1. default V replace(K key, V value) {
  2. V curValue;
  3. if (((curValue = get(key)) != null) || containsKey(key)) {
  4. curValue = put(key, value);
  5. }
  6. return curValue;
  7. }

只有在当前Map中包含key,才用value去替换原来的值,否则什么也不做。

  1. Map<String, String> map = new HashMap<>();
  2. map.put("a", "A");
  3. map.put("b", "B");
  4. map.replace("c", "1");
  5. map.replace("b", "1");
  6. System.out.println(map.get("c")); // null
  7. System.out.println(map.get("b")); // 1

replace(K key, V oldValue, V newValue)

  1. default boolean replace(K key, V oldValue, V newValue) {
  2. Object curValue = get(key);
  3. if (!Objects.equals(curValue, oldValue) ||
  4. (curValue == null && !containsKey(key))) {
  5. return false;
  6. }
  7. put(key, newValue);
  8. return true;
  9. }

只有在当前Map中key的映射存在且映射的值等于oldValue时才用newValue去替换原来的值,否则什么也不做。

  1. Map<String, String> map = new HashMap<>();
  2. map.put("a", "A");
  3. map.put("b", "B");
  4. map.replace("a", "1", "2");
  5. map.replace("b", "B", "2");
  6. System.out.println(map.get("a")); // A
  7. System.out.println(map.get("b")); // 2

replaceAll

  1. default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
  2. Objects.requireNonNull(function);
  3. for (Map.Entry<K, V> entry : entrySet()) {
  4. K k;
  5. V v;
  6. try {
  7. k = entry.getKey();
  8. v = entry.getValue();
  9. } catch(IllegalStateException ise) {
  10. // this usually means the entry is no longer in the map.
  11. throw new ConcurrentModificationException(ise);
  12. }
  13. // ise thrown from function is not a cme.
  14. v = function.apply(k, v);
  15. try {
  16. entry.setValue(v);
  17. } catch(IllegalStateException ise) {
  18. // this usually means the entry is no longer in the map.
  19. throw new ConcurrentModificationException(ise);
  20. }
  21. }
  22. }

该方法签名为replaceAll(BiFunction<? super K,? super V,? extends V> function),作用是对Map中的每个映射执行function指定的操作,并用function的执行结果替换原来的value

比如:

  1. Map<String, String> map = new HashMap<>();
  2. map.put("a", "A");
  3. map.put("b", "B");
  4. map.replaceAll((k, v) -> v.toLowerCase());
  5. map.forEach((k, v)-> {
  6. System.out.println(k + "=" + v);
  7. });
  8. // a=a
  9. // b=b

merge

  1. default V merge(K key, V value,
  2. BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
  3. Objects.requireNonNull(remappingFunction);
  4. Objects.requireNonNull(value);
  5. V oldValue = get(key);
  6. V newValue = (oldValue == null) ? value :
  7. remappingFunction.apply(oldValue, value);
  8. if(newValue == null) {
  9. remove(key);
  10. } else {
  11. put(key, newValue);
  12. }
  13. return newValue;
  14. }

value和remappingFunction不能为null
如果Map中key对应的映射不存在或者为null,则将value关联到key上;否则执行remappingFunction,如果执行结果为null则删除key的映射,否则用该结果跟key关联。

比如:

  1. Map<String, String> map = new HashMap<>();
  2. map.put("e", "E");
  3. map.merge("f", "F", String::concat);
  4. map.merge("e", "F", String::concat);
  5. System.out.println("map.get(\"f\")="+map.get("f")); // map.get("f")=F
  6. System.out.println("map.get(\"e\")="+map.get("e")); // map.get("e")=EF

compute

  1. default V compute(K key,
  2. BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
  3. Objects.requireNonNull(remappingFunction);
  4. // 获取key对应的值
  5. V oldValue = get(key);
  6. //获取新值
  7. V newValue = remappingFunction.apply(key, oldValue);
  8. // 如果新值为null,并且key存在,则删除key;否则把新值赋值给key
  9. if (newValue == null) {
  10. // delete mapping
  11. if (oldValue != null || containsKey(key)) {
  12. // something to remove
  13. remove(key);
  14. return null;
  15. } else {
  16. // nothing to do. Leave things as they were.
  17. return null;
  18. }
  19. } else {
  20. // add or replace old mapping
  21. put(key, newValue);
  22. return newValue;
  23. }
  24. }

比如:

  1. Map<String, String> map = new HashMap<>();
  2. map.put("b", "B");
  3. String val = map.compute("b", (k, v) -> null);
  4. String val2 = map.compute("c", (k, v) -> v + "+v");
  5. System.out.println(val); // null
  6. System.out.println(val2); // null+v

computeIfAbsent

  1. default V computeIfAbsent(K key,
  2. Function<? super K, ? extends V> mappingFunction) {
  3. Objects.requireNonNull(mappingFunction);
  4. V v;
  5. if ((v = get(key)) == null) {
  6. V newValue;
  7. if ((newValue = mappingFunction.apply(key)) != null) {
  8. put(key, newValue);
  9. return newValue;
  10. }
  11. }
  12. return v;
  13. }

当Map中不存在key值的映射或映射值为null时,调用mappingFunction,并在mappingFunction执行结果非null时,将结果赋值给key。

比如(输入每个字母的位置):

  1. List<String> list = Lists.newArrayList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g");
  2. Map<String, List<Integer>> positionsMap = new HashMap<>();
  3. for (int i = 0; i < list.size(); i++) {
  4. positionsMap.computeIfAbsent(list.get(i), k -> Lists.newArrayListWithCapacity(1)).add(i);
  5. }
  6. System.out.println(positionsMap);
  7. // {a=[0], b=[1, 2], c=[3, 4, 5], d=[6, 7, 8], f=[9, 10], g=[11]}

相关文章