The pit of Collectors.groupingBy in Java8, the grouping is out of order

Create an entity first

@Data
public class User {
    
    
    private String date;
    private String name;
    private String age;

    public User(String date, String name, String age) {
    
    
        this.date = date;
        this.name = name;
        this.age = age;
    }
}

group by date

    public static void main(String[] args) {
    
    
        List<User> userList = new ArrayList<>();
        for (int x = 1; x < 30; x++) {
    
    
            User user = new User("2021-06-" + (x < 10 ? "0" + x : x), "张三", x);
            userList.add(user);
        }

        Map<String, List<User>> userMap = userList.stream().collect(Collectors.groupingBy(User::getDate));
        System.out.println(userMap);
    }

You can see that the order of the Map after grouping is out of order.
insert image description here
Why is this method out of order? Look at the source code

    public static <T, K, A, D>
    Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
                                          Collector<? super T, A, D> downstream) {
    
    
        return groupingBy(classifier, HashMap::new, downstream);
    }

As you can see, this method returns HashMap by default. We all know that HashMap is unordered. Now that we find the problem, we can solve it. We can manually pass an ordered Map into it.

    public static void main(String[] args) {
    
    
        List<User> userList = new ArrayList<>();
        for (int x = 1; x < 30; x++) {
    
    
            User user = new User("2021-06-" + (x < 10 ? "0" + x : x), "张三", x);
            userList.add(user);
        }

        Map<String, List<User>> userMap = userList.stream().collect(Collectors.groupingBy(User::getDate, LinkedHashMap::new, Collectors.toList()));
        System.out.println(userMap);
    }

You can see that the grouped Map has become ordered
insert image description here

It is also possible to additionally remove the sort

		// 将日期key取出,去重、排序
        List<String> dateList = new ArrayList<>(userMap.keySet());
        dateList = dateList.stream().distinct().collect(Collectors.toList());
        Collections.sort(dateList);
        List<String> dateList= userList.stream().map(User::getDate).collect(Collectors.toList());
        // (日期 + 时点)抽取Map
        Map<String, Double> dataMap = dataList.stream().collect(Collectors.toMap(v -> v.getIssue() + " " + v.getTimeValue(), UserDO::getValue));
		// List属性求和
		Double sumValue = dataList.stream().filter(v -> v.getValue() != null).mapToDouble(v -> v.getValue().doubleValue()).sum();

Guess you like

Origin blog.csdn.net/qq_39486119/article/details/118188002