用例:
Map map=new HashMap<>();
String[][] user= {{"harry","123"},{"kann","ff"},{"bob","fe88"},{"felton","okjj"}};
for(String[] u:user) {
map.put(u[0], u[1]);
}
1. default V compute(K key,BiFunction super K, ? super V, ? extends V> remappingFunction)
计算K,V之间映射关系,根据重映射函数返回新的V值,若返回null,直接删除该组映射.(如果最初不存在则保持不存在)。 如果重映射函数本身引发(未检查)异常,则重新引导异常,并且当前映射保持不变。BiFunction接口的apply的入参为key、oldValue。
//此时Harry的字符串长度>"123",则返回null,此组映射被直接删除
map.compute("harry", (k,v)->k.length()>v.length()?null:v);
map.forEach((k,v)->System.out.println(k+"-"+v));
//注意不要在计算过程中修改该映射,否则抛出ConcurrentModificationException[map本身的default方法并未throw exception,但其实现类都应重写抛出该异常]
// map.compute("kann", (k,v)->{
// return map.remove("kann");
// });
2.default V computeIfAbsent(K key, Function super K, ? extends V> mappingFunction)
//if K-V值缺失,then 计算
/**若lambda式返回值!=null, 且Key不存在, 则在map中新增该组(K,V);
* 且若Key存在, 且原value!=null,则不做操作;
* 但原value=null,则更新value值;
* 若lambda式返回值=null, 则不做操作;
*/
String empty=map.computeIfAbsent("harry", v->null);
map.computeIfAbsent("grant", v->"jjjds");
map.computeIfAbsent("felton", v->null);
System.out.println(empty);
map.forEach((k,v)->System.out.println(k+"-"+v));
3.default V computeIfPresent(K key,BiFunction super K, ? super V, ? extends V> remappingFunction)
/**如果指定的密钥的值存在且非空,则尝试计算给定密钥及其当前映射值的新映射。 如果重
* 映射函数返回null ,则映射将被删除。 如果重映射函数本身引发(未检查)异常,则
* 重新引导异常,并且当前映射保持不变。 重映射功能在计算过程中不应修改此映射。
*/
map.put("harry", null);
String present=map.computeIfPresent("bob", (k,v)->"on");
map.computeIfPresent("grant", (k,v)->null);
System.out.println(present);
map.forEach((k,v)->System.out.println(k+"-"+v));
注:1.以上3个方法都不应在计算过程中修改原映射,否则map的实现类将抛出ConcurrentModificationException.
2.注意jdk8中不要尝试对ConcurrentHashMapz类中的computeIfAbsent方法使用递归,会导致一个bug,产生死循环.
/**
* 注意在ConcurrentHashMap中使用computeIfAbsent方法递归会导致一个bug,
* 使计算机进入一个死循环。实例代码如下:
* resolved in jdk 9,在jdk 8避免以递归方式调用该方法
* 参考: https://bugs.openjdk.java.net/browse/JDK-8062841
* http://mp.weixin.qq.com/s/O6UmB7YDKIYtNvqCOjNwDQ
* */
// Map curmap = new ConcurrentHashMap<>(16);
// curmap.computeIfAbsent(
// "AaAa",
// key -> {
// return curmap.computeIfAbsent(
// "BBBB",
// key2 -> 42);
// }
// );
4.default void forEach(BiConsumer super K, ? super V> action)
对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。 除非实现类另有指定,否则按照进入设置迭代的顺序执行操作(如果指定了迭代顺序)。操作引发的异常被转发给调用者。
map.forEach((k,v)->System.out.println(k+"-"+v));
5. default void replaceAll(BiFunction super K, ? super V, ? extends V> function)
将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。 函数抛出的异常被转发给调用方。
map.replaceAll((s1,s2)->{
if(s1.length()<=3) {
s2="";
}
return s2;
});
6. public void putAll(Map extends K, ? extends V> m)[复习旧的方法]
将指定地图的所有映射复制到此地图。 这些映射将替换此映射对当前在指定映射中的任何键的任何映射。
//原api putAll--把map2放入map中,重复的key更新为map2的value
Map map2=new HashMap<>();
map2.put("rola", "8884");
map2.put("kann", "dew");
map.putAll(map2);
map.forEach((k,v)->System.out.println(k+"-"+v));
System.out.println(map2.size());
7.default V putIfAbsent(K key, V value) [旧]
如果指定的键尚未与某个值相关联(或映射到 null
), null
其与给定值相关联并返回 null
,否则返回当前值。
/**
* putIfAbsent与computeIfAbsent实现目的相同,区别是后者可使用lambda表达式
* 返回一个重映射函数,后者可以取代前者。
*/
map.putIfAbsent("bob", "in");
map.putIfAbsent("kyle", "48eww");
map.put("harry", "on");
map.forEach((k,v)->System.out.println(k+"-"+v));
System.out.println("5.----------------------------");
8.default V merge(K key, V value, BiFunction super V, ? super V, ? extends V> remappingFunction)
如果指定的键尚未与值相关联或与null相关联,则将其与给定的非空值相关联。 否则,将关联值替换为给定重映射函数的结果,如果结果为null
,则将其null
。如果重映射函数返回null
,则映射将被删除。 如果重映射函数本身引发(未检查)异常,则重新引导异常,并且当前映射保持不变。
/**
* 功能大部分与compute相同,不同之处在于BiFunction中apply的参数,入参为
* oldValue、value,调用merge时根据两个value进行逻辑处理并返回value。
*/
map.merge("bob", "in", (o,n)->n+o.toUpperCase());
map.merge("kann", "in", (o,n)->null);
map.merge("harry", "on", (o,n)->"ff");
map.forEach((k,v)->System.out.println(k+"-"+v));
9.default V getOrDefault(Object key, V defaultValue)
返回指定键映射到的值,如果此映射不包含键的映射,则返回 defaultValue 。
String getDefault1=map.getOrDefault("conner","not exists");
String getDefault2=map.getOrDefault("rola","not exists");
System.out.println(getDefault1);
System.out.println(getDefault2);