1. Java8新加入的lambda方法
接口类型
新加入的方法
Map
forEach()、replaceAll()、merge()、compute()、computeIfAbsent()、computeIfPresent()
由于继承关系,他们相应的子类也都会继承这些新方法。
2. forEach() 该方法签名为void forEach(BiConsumer<? super K,? super V> action),作用是对Map中的每个映射执行action指定的操作,其中BiConsumer是一个函数接口,里面有一个待实现方法void accept(T t, U u)。BinConsumer接口名字和accept()方法名字都不重要。
2.1 示例:遍历输出Map 需求:假设有一个成绩单Map,遍历输出Map中的所有映射关系.
2.2 Java8以前的代码 HashMap<String ,Integer > map = new HashMap<>();map .put("张三" , 62 );map .put("李四" , 66 );map .put("王麻子" , 89 ); for(Map .Entry<String ,Integer > entry : map .entrySet()){ System.out.println(entry.getKey() + " => " + entry.getValue()); }
2.3 匿名内部类代码 HashMap<String ,Integer > map = new HashMap<>();map .put("张三" , 62 );map .put("李四" , 66 );map .put("王麻子" , 89 );map .forEach(new BiConsumer<String , Integer >() { @Override public void accept(String s, Integer integer ) { System.out.println(s + " => " + integer ); } });
2.4 使用lambda HashMap<String ,Integer> map = new HashMap<>();map .put("张三" , 62 );map .put("李四" , 66 );map .put("王麻子" , 89 );map .forEach((k,v)-> { System.out.println(k + " => " + v); }) ;/** 输出: 李四 => 66 张三 => 62 王麻子 => 89 */
3.replaceAll() 该方法签名为replaceAll(BiFunction<? super K,? super V,? extends V> function),作用是对Map中的每个映射执行function指定的操作,并用function的执行结果替换原来的value,其中BiFunction是一个函数接口,里面有一个待实现方法R apply(T t, U u)
3.1 示例:将单词都转换成大写 需求:有一个数字到对应英文单词的Map,将单词都转换成大写.
3.2 Java8以前的代码 HashMap<Integer ,String > map = new HashMap<>();map .put(1 , "c" );map .put(2 , "go" );map .put(3 , "java" );map .put(4 , "php" ); for (Map .Entry<Integer ,String > entry : map .entrySet()){ entry.setValue(entry.getValue().toUpperCase()); } System.out.println(map );
3.3 匿名内部类代码 HashMap<Integer ,String > map = new HashMap<>();map .put(1 , "c" );map .put(2 , "go" );map .put(3 , "java" );map .put(4 , "php" );map .replaceAll(new BiFunction<Integer , String , String >() { @Override public String apply(Integer integer , String s) { return s.toUpperCase(); } }); System.out.println(map );
3.4 使用lambda HashMap<Integer,String > map = new HashMap<>();map .put(1 , "c" );map .put(2 , "go" );map .put(3 , "java" );map .put(4 , "php" );map .replaceAll((k,v)->v.toUpperCase()) ;System .out .println (map ) ;// 输出:{1=C , 2=GO , 3=JAVA , 4=PHP }
4. merge() 该方法签名为merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)。作用是:它将新的值赋值到 key (如果不存在)或更新给定的key 值对应的 value。即key存在则更新,不存在则赋值。
4.1 错误信息拼接 一个比较常见的场景是将新的错误信息拼接到原来的信息上,比如:
HashMap<String , String > stringStringHashMap = new HashMap<>(1 ); stringStringHashMap.put("error" , "执行错误," ); System.out.println(stringStringHashMap); // {error=执行错误} // 使用merge stringStringHashMap.merge("error" , "其他错误信息....." , (v1, v2) -> v1 + v2) ;System .out .println (stringStringHashMap) ; // {error =执行错误,其他错误信息.....}
4.2 其他示例
5.compute() 该方法签名为compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction),作用是把remappingFunction的计算结果关联到key上,如果计算结果为null,则在Map中删除key的映射.
5.1 统计一个List 中每个元素出现的次数 List<String> list = Arrays.asList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g");System .out .println("使用 compute 计算元素出现的次数:"); Map<String, Integer > countsMap = new HashMap<>(6 ); // 此时:新值 = 旧值 + 1 list.forEach (str -> countsMap.compute(str, (k, v) -> v == null ? 1 : v + 1 ));System .out .println(countsMap);
6.computeIfAbsent() 该方法签名为V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction),作用:只有在当前Map中不存在key值的映射或映射值为null时,才调用mappingFunction,并在mappingFunction执行结果非null时,将结果跟key关联.
6.1 示例:条件判断和添加操作合二为一 computeIfAbsent()常用来对Map的某个key值建立初始化映射.比如我们要实现一个多值映射,Map的定义可能是Map<K,Set>,要向Map中放入新值,可通过如下代码实现
6.2 Java8以前的代码 Map <Integer , Set <String >> map = new HashMap<>();if (map .containsKey(1 )){ map .get(1 ).add("PHP" ); }else { Set <String > valueSet = new HashSet<String >(); valueSet.add("PHP" ); map .put(1 , valueSet); }
6.3 使用lambda Map <Integer , Set <String >> map = new HashMap<>();map .computeIfAbsent(1 , v -> new HashSet<String >()).add("Java" );
7.computeIfPresent() 该方法签名为V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction),作用跟computeIfAbsent()相反,即,只有在当前Map中存在key值的映射且非null时,才调用remappingFunction,如果remappingFunction执行结果为null,则删除key的映射,否则使用该结果替换key原来的映射.
7.1 使用示例 HashMap<String, Integer> map = new HashMap<>();map .put ("1" , 1 );map .put ("2" , 2 );map .put ("3" , 3 );map .put ("4" , 3 ); //只对map 中存在的key 对应的value进行操作 Integer integer = map .computeIfPresent("3" , (k, v) -> v + 1 ); System.out.printf ("修改key=3得值为: %d\n" , integer ); System.out.printf ("修改后的map为: %s\n" , map .toString()); // 触发remappingFunction,并返回执行结果为null,从而删除key =4 map .computeIfPresent("4" , (k, v) -> { System.out.println("调用remappingFunction = [k=" + k + "; v=" + v + "]" ); return null; }); System.out.printf ("触发remappingFunction后的,map为: %s\n" , map .toString());