Java-Map在JDK8中新增方法

JDK8–Map新增方法

因在看部分源码时,发现用到一些Map的新增方法但是并不知道其具体含义,故了解并整理。

computer

解释

简单点说就是针对key的value重新设值,具体的值取决于自定义函数返回值。
自定义函数返回值不等于空,则会将自定义函数返回的value设置成key对应的值。
如果key对应的value不等于空但是自定义函数返回值等于空则会删除这个key。

V oldValue = map.get(key);
// 通过自定义的BiFunction,对key和oldValue处理后返回新的数据
 V newValue = remappingFunction.apply(key, oldValue);
// 如果oldValue不为空
 if (oldValue != null ) {
     // 并且自定义的的BiFunction返回的newValue不等于空
    if (newValue != null)
        // 替换直接的oldValue
       map.put(key, newValue);
    else
        // 如果自定义的的BiFunction返回的newValue等于空,则移除该key
       map.remove(key);
 } else {
     // 如果oldValue等于空,newValue不等于空,则存放key,newValue到map中
    if (newValue != null)
       map.put(key, newValue);
    else
        // 否则返回null
       return null;
 }

简单使用

 Map<String, String> map = new HashMap<String, String>();
// 计算该key,如果value等于null则设置key=1,value=1,否则将该key对应的value+1存放到对应key
map.compute("1", (k, v) -> {
    return v == null ?
        String.valueOf(1) : String.valueOf(Integer.valueOf(v) + 1);
});
 System.out.println(map.containsKey("1"));//输出true
// 如果自定义函数返回null,则会删除该key
 map.compute("1", (k, v) -> {
        return null;
    });

 System.out.println(map.containsKey("1"));//输出false

应用场景

统计一个字符串中字符出现的次数

String str = "hello, i am vary happy! nice to meet you, my name is demo";
// jdk8之前的写法
HashMap<Character, Integer> result1 = new HashMap<>(32);
for (int i = 0; i < str.length(); i++) {
    char curChar = str.charAt(i);
    Integer curVal = result1.get(curChar);
    if (curVal == null) {
        curVal = 1;
    } else {
        curVal += 1;
    }
    result1.put(curChar, curVal);
}
 result1.forEach((k, v) -> {
     System.out.println(k + "--" + v);
 });

// 清除信息
result1.clear();

// jdk8的写法
for (int i = 0; i < str.length(); i++) {
    char curChar = str.charAt(i);
    result1.compute(curChar, (key, oldValue) -> {
        return oldValue == null ? 1 : oldValue + 1;
    });
}

// map中的forEach使用
result1.forEach((k, v) -> {
    System.out.println(k + "--" + v);
});

computerIfPresent

解释

简单点说:如果key对应的value存在就计算,如果key对应的value不存在就不处理。如果key对应的value存在,但是函数返回null,则会移除该key。

//如果key对应的value存在就处理,不存在不处理
if (map.get(key) != null) {
    // 获取该key对应的value
     V oldValue = map.get(key);
    // 通过自定义的BiFunction函数,返回新的value
     V newValue = remappingFunction.apply(key, oldValue);
    // 如果新的value不等于空,则将key的value设置成新的value,否则移除
     if (newValue != null)
         map.put(key, newValue);
     else
         map.remove(key);
 }

简单使用


Map<String, Integer> map = new HashMap<>();
map.put("1", 1);
map.computeIfPresent("1", (key, oldValue) -> {
    return oldValue + 1;
});
map.get("1");//输出2


// 如果映射关系返回null,则将当前的key移除
map.computeIfPresent("1", (key, oldValue) -> {
    return null;
});
map.containsKey("1");//返回false,不存在

应用场景

处理map中的数字减

// jdk8之前的 
public static void reduce1() {
        Map<String, Integer> map = new HashMap<>();
        // 如果1对应的值存在则进行计算,这里不会计算
        Integer integer = map.get("1");
        //如果没有这个判断,会报错
        if (integer == null) {
            return;
        }
        integer -= 1;

 }
// jdk8版本
public static void reduce2() {
    Map<String, Integer> map = new HashMap<>();
    map.computeIfPresent("1", (key, oldValue) -> {
        return oldValue -= 1;
    });
}

computerIfAbsent

解释

简单点说当key对应的value没有的时候执行自定义函数并且将自定义函数返回值设置成value。

 if (map.get(key) == null) {
     // 通过自定义的BiFunction函数返回数据
     V newValue = mappingFunction.apply(key);
     // 如果不是null,则设置
     if (newValue != null)
         map.put(key, newValue);
 }

简单使用

Map<String, String> map = new HashMap<String, String>();
map.put("world", "java");

// 如果对应key不存在,则执行对应的默认值,针对当前map存放key,value
map.computeIfAbsent("hello", key -> "world");
map.get("hello"); // 输出world
map.computeIfAbsent("world", key -> "c++");
map.get("world");// 输出java

应用场景

读取字典并存放到对应的map结构中

//jdk8之前的代码
Map<String, Map<String, String>> newMap = new HashMap<>();
Map<String, String> value = newMap.get("productUnit");
 if(value==null){
 	value = new HashMap<>();
 }else{
 	value.put("he","she");
 }

//jdk8代码
newMap = new HashMap<>();
//如果不存在,则创建一个map;存在则不会执行该自定义函数
newMap.computeIfAbsent("productUnit", key -> new HashMap<>());
newMap.get("productUnit").put("he", "she");

merge

解释

简单点描述:如果key对应的value不存在,则将第二个参数的value设置成value。
如果key对应的value存在,则将自定义BiFunction函数返回值设置成value。

// 获取key对应的value 
V oldValue = map.get(key);
// 如果value等于空,则返回设置的value,如果不等于空,则返回自定义函数的返回值
 V newValue = (oldValue == null) ? value :
              remappingFunction.apply(oldValue, value);
// 如果新的value等于空,则移除该key,否则将新的value存放到对应的key中
 if (newValue == null)
     map.remove(key);
 else
     map.put(key, newValue);
 

简单使用

Map<String, Integer> map = new HashMap<String, Integer>();
map.put("1", 1);
// merge
map.merge("1", 1, Integer::sum);//累加value
map.merge("2", 1, Integer::sum);//累加value
map.get("1");// 输出2
map.get("2");// 输出1

应用场景

统计学生的总成绩

public class Score {
    public Integer sid;
    public String scoreName;
    public Integer score;

    public Score(Integer sid, String scoreName, Integer score) {
        this.sid = sid;
        this.scoreName = scoreName;
        this.score = score;
    }
}

//要统计每个学生的总成绩,
List<Score> list = new ArrayList<>();
list.add(new Score(1, "chinese", 100));
list.add(new Score(1, "english", 103));
list.add(new Score(1, "math", 32));
list.add(new Score(2, "english", 65));
list.add(new Score(2, "chinese", 53));

System.out.println(sum1(list));
System.out.println(sum2(list));
System.out.println(sum3(list));

以前

//传统写法
public static Map<Integer, Integer> sum1(List<Score> list) {
    Map<Integer, Integer> map = new HashMap<>();
    for (Score score : list) {
        if (map.containsKey(score.sid)) {
            map.put(score.sid,
                    map.get(score.sid) + score.score);
        } else {
            map.put(score.sid, score.score);
        }
    }
    return map;
}

jdk8-V1

// jdk8的写法 v1
public static Map<Integer, Integer> sum2(List<Score> list) {
    Map<Integer, Integer> map = new HashMap<>();
    for (Score score : list) {
        //如果没有该生的信息,则设置默认成绩是莫课的成绩
        map.merge(score.sid, score.score, Integer::sum);
    }
    return map;
}

jdk8-V2

采用流处理

public static Map<Integer, Integer> sum3(List<StudentScore> list) {
    Map<Integer, Integer> map = new HashMap<>();
    list.stream().forEach(studentScore -> map.merge(studentScore.sid, studentScore.score, Integer::sum));
    return map;
}

putIfAbsent

解释

简单点说:更新value为空的key,否则不更新。

V v = map.get(key);
// 如果value等于空,设置传递的value到map中
 if (v == null)
     v = map.put(key, value);
// 否则返回value
 return v;

简单使用

Map<String, Integer> map = new HashMap<>();
// 为不存在的key设置值,则返回null,因为更新为空的value
Integer integer = map.putIfAbsent("1", 2);
System.out.println(integer);//输出null


// 如果是为存在的key并且value不为null的设置,则返回map中key对应的值
integer = map.putIfAbsent("1", 3);
System.out.println(integer);//输出2

应用场景

暂未想到

replaceAll

解释

简单点说:可以将满足条件的key或者value的entry对应的value更新。

 for (Map.Entry<K, V> entry : map.entrySet())
     // 将该entry的value更新为自定义函数BiFunction的返回值
     entry.setValue(function.apply(entry.getKey(), entry.getValue()));

简单使用

Map<String, Integer> map = new HashMap<>();

map.put("1",2);
map.put("2",2);
map.put("3",3);
// 将key和value都为2所对应的key的value设置为1,否则不变
map.replaceAll((key, value) -> {
    return key.equals("2") || value == 2 ? 1 : value;
});
System.out.println(map);// 输出{1=1, 2=1, 3=3}

应用场景

暂未想到

参考文档

  • oracle官方API

你可能感兴趣的:(Java)