Java 8 in merge Map Sao operation of () usage

Java 8 is tantamount to the maximum the characteristics of more function-oriented, such as the introduction of the lambdaother, allows for better functional programming. Inter some time ago accidentally discovered map.merge()method, there was still good use, to do some simple text related presentations. First we look at an example.

merge() how to use?

Suppose we have such a period of business logic, I have a list of student achievement object, the object contains the student's name, the subject, subjects scores three properties, each student is required to obtain a total score. Added to the list as follows:

    private List<StudentScore> buildATestList() {
        List<StudentScore> studentScoreList = new ArrayList<>();
        StudentScore studentScore1 = new StudentScore() {{
            setStuName("张三");
            setSubject("语文");
            setScore(70);
        }};
        StudentScore studentScore2 = new StudentScore() {{
            setStuName("张三");
            setSubject("数学");
            setScore(80);
        }};
        StudentScore studentScore3 = new StudentScore() {{
            setStuName("张三");
            setSubject("英语");
            setScore(65);
        }};
        StudentScore studentScore4 = new StudentScore() {{
            setStuName("李四");
            setSubject("语文");
            setScore(68);
        }};
        StudentScore studentScore5 = new StudentScore() {{
            setStuName("李四");
            setSubject("数学");
            setScore(70);
        }};
        StudentScore studentScore6 = new StudentScore() {{
            setStuName("李四");
            setSubject("英语");
            setScore(90);
        }};
        StudentScore studentScore7 = new StudentScore() {{
            setStuName("王五");
            setSubject("语文");
            setScore(80);
        }};
        StudentScore studentScore8 = new StudentScore() {{
            setStuName("王五");
            setSubject("数学");
            setScore(85);
        }};
        StudentScore studentScore9 = new StudentScore() {{
            setStuName("王五");
            setSubject("英语");
            setScore(70);
        }};

        studentScoreList.add(studentScore1);
        studentScoreList.add(studentScore2);
        studentScoreList.add(studentScore3);
        studentScoreList.add(studentScore4);
        studentScoreList.add(studentScore5);
        studentScoreList.add(studentScore6);
        studentScoreList.add(studentScore7);
        studentScoreList.add(studentScore8);
        studentScoreList.add(studentScore9);

        return studentScoreList;
    }
复制代码

We look at the conventional approach:

        ObjectMapper objectMapper = new ObjectMapper();
        List<StudentScore> studentScoreList = buildATestList();

        Map<String, Integer> studentScoreMap = new HashMap<>();
        studentScoreList.forEach(studentScore -> {
            if (studentScoreMap.containsKey(studentScore.getStuName())) {
                studentScoreMap.put(studentScore.getStuName(), 
                                    studentScoreMap.get(studentScore.getStuName()) + studentScore.getScore());
            } else {
                studentScoreMap.put(studentScore.getStuName(), studentScore.getScore());
            }
        });

        System.out.println(objectMapper.writeValueAsString(studentScoreMap));

// 结果如下:
// {"李四":228,"张三":215,"王五":235}
复制代码

Then let's look at merge()how it is done:

        Map<String, Integer> studentScoreMap2 = new HashMap<>();
        studentScoreList.forEach(studentScore -> studentScoreMap2.merge(
          studentScore.getStuName(),
          studentScore.getScore(),
          Integer::sum));

        System.out.println(objectMapper.writeValueAsString(studentScoreMap2));

// 结果如下:
// {"李四":228,"张三":215,"王五":235}
复制代码

merge() Brief introduction

merge() It can be appreciated that: it assigned to the new key value (if not present) or update the given key value corresponding to the value, its source code is as follows:

    default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);
        Objects.requireNonNull(value);
        V oldValue = this.get(key);
        V newValue = oldValue == null ? value : remappingFunction.apply(oldValue, value);
        if (newValue == null) {
            this.remove(key);
        } else {
            this.put(key, newValue);
        }

        return newValue;
    }
复制代码

We can see the principle is very simple, this method accepts three parameters, a key value, a value, a remappingFunction, if the given key does not exist, it becomes put(key, value). However, if the key has some value, we remappingFunctioncan choose to merge the way, and then combined to give the newValueassignment to the original key.

scenes to be used

This is still relatively more usage scenarios, such as grouping sum of these operations, although the relevant stream in the groupingBy()method, but if you want to do some other operations in a loop when, merge()still a very good choice.

other

In addition merge()to the methods, I also saw some of Java 8 mapother related methods, such as putIfAbsent, , compute(), computeIfAbsent(), computeIfPresentthe way we look at the name should know what it means, so presented here do not do too much, interest can be simply read the source code (both quite understandable), where we posted about compute()(Map.class)the source code, the return value is the new value calculated:

    default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);
        V oldValue = this.get(key);
        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue == null) {
            if (oldValue == null && !this.containsKey(key)) {
                return null;
            } else {
                this.remove(key);
                return null;
            }
        } else {
            this.put(key, newValue);
            return newValue;
        }
    }
复制代码

to sum up

In this paper a brief introduction about Map.merge()the method, in addition, Java 8 HashMapimplementation uses TreeNodeand red-black tree, may be a little difficult to read on the source, but still on a similar principle, compute()empathy. So, be sure to look at the source code, do not know where to read more naturally understand the practice.

link

Guess you like

Origin juejin.im/post/5d9b455ae51d45782b0c1bfb