putIfAbsent: 如果指定的键没有对应的值(没有该键或者该键对应的值是空),K为键,V为值添加到Map中;
public static void testPutIfAbsent(){
Map<String, String> family = new HashMap<>();
// family.put("Teo",null);
family.putIfAbsent("Teo","Star Wars");
System.out.println(family);
}
computeIfAbsent:如果指定的键没有对应的值(没有该键或者该键对应的值是空),那么使用该键计算新的值,并将其添加到Map中;
public static void testComputeIfAbsent() {
HashMap<String, List<String>> movies = new HashMap<>();
// computeIfAbsent方法的第二个值接收一个Function
// 如果只是简单的赋一个初始值,用putIfAbsent方法就好了
movies.computeIfAbsent("zhl", DishTest::addMovies);
movies.forEach((k, v) -> System.out.println(k + " " + v));
}
public static List<String> addMovies(String key){
ArrayList<String> movies = new ArrayList<String>();
movies.add("让子弹飞");
movies.add("太阳照常升起");
return movies;
}
computeIfPresent:如果指定的键在Map中存在,就计算该键的新值,并将其添加到Map中;
compute:使用指定的键计算新的值,并将其存储到Map中。
merge:如果指定的键并没有关联值,或者关联的是一个空值,那么[merge]会将它关联到指定的非空值。否则,[merge]会用给定映射函数的[返回值]替换该值,如果映射函数的返回值为空就删除[该键]。(懵逼的话看最后一段代码中注释)
假设你需要合并两个临时的Map,它们可能是两个不同联系人群构成的Map。可以像下面这样,使用putAll完成这一任务:
只要你的Map中不含有重复的键,这段代码就会工作得非常好。如果你想要在合并时对值有更加灵活的控制,那么可以考虑使用Java 8中新引入的merge方法。该方法使用BiFunction方法处理重复的键。例如,Cristina同时在“家庭”和“朋友”这两个群里,但其在不同群中对应的电影不同:
public static void testMerge() {
Map<String, String> family = new HashMap<>();
family.put("Teo", "Star Wars");
family.put("Cristina", "James Bond");
Map<String, String> friends = new HashMap<>();
friends.put("Raphael", "Star Wars");
friends.put("Cristina", "Matrix");
HashMap<String, String> everyOne = new HashMap<>(family);
// 如果存在重复的键,就连接两个值
friends.forEach((k, v) -> everyOne.merge(k, v, (movie, movie2) -> movie + " & " + movie2));
System.out.println(everyOne);
}
统计一个字符串中每个字母出现的次数
/**
* 最原始的使用for循环实现
*/
public static void testFor() {
HashMap<Character, Integer> map = new HashMap<>();
String str = "aaabbbbbbbvvvvvvvvvvsfasdgasfaeeeewwww";
for (char c : str.toCharArray()) {
if (map.get(c) == null) {
map.put(c, 1);
} else {
map.put(c, map.get(c) + 1);
}
}
System.out.println(map);
}
public static void testComputeIfAbsent() {
HashMap<Character, Integer> map = new HashMap<>();
String str = "aaabbbbbbbvvvvvvvvvvsfasdgasfaeeeewwww";
for (char c : str.toCharArray()) {
//map.computeIfAbsent(c, key -> 0);
//computeIfAbsent方法的第二个值接收一个Function,用不到的时候可以用putIfAbsent替代
map.putIfAbsent(c, 0);
map.computeIfPresent(c, (key, value) -> value + 1);
}
System.out.println(map);
}
public static void testMerge2() {
//统计一个字符串中字符出现的次数
HashMap<Character, Integer> map = new HashMap<>();
String str = "aaabbbbbbbvvvvvvvvvvsfasdgasfaeeeewwww";
for (char c : str.toCharArray()) {
// 第一个参数是要添加的键
// 第二个参数是与键关联的非空值,该值将与现有的值合并,如果没有当前值,或者该键关联的当今值为空,就将该键关联到非空值。
// 因为该键的返回值是空,所以第一轮里键的值被赋值为1。
// 接下来的一轮,由于键已经初始化为1,因此后续的操作由BiFunction方法对count进行递增。
// 第三个参数的第一个值表示的是当要添加的键已存在时对应的值
// 第三个参数的第二个值就是第二个参数的值
map.merge(c, 1, (value, count) -> value + count);
}
System.out.println(map);
}
参考java实战(第2版)