Java Stream之Collectors.groupingBy分组导致顺序无序问题

Collectors.groupingBy是Java steam常用分组方法,但默认情况下分组的数据是无序的(因为默认使用的是HashMap),groupingBy有三个参数:

  1. 第一个参数就是key的Function了,指定分组按照什么分类
  2. 第二个参数是一个map工厂,也就是最终结果的容器,一般默认的是采用的HashMap::new,指定分组最后用什么容器保存返回
  3. 第三个参数是一个downstream,类型是Collector,也是一个收集器,指定按照第一个参数分类后,对应的分类的结果如何收集

代码复现:


        SearchResponse search = null;
        try {
            search = client.search(s -> s.index("tbanalyzelist")
                    .query(
                            q -> q.matchAll(m -> m)
                    )
                    .sort(o -> o.field(f -> f.field("openTime").order(SortOrder.Asc)))
                    .from(0)
                    .size(2000)
                    , Map.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        List AnalyzeList = search.hits().hits().stream().map(f -> f.source()).collect(Collectors.toList());
        for(Map item : AnalyzeList){
            //System.out.println("在线机器分析:"+item);
            System.out.print("机器编号:"+item.get("machineId") + "\t");
            System.out.print("机器持续开机时间:"+item.get("duration") + "\t");
            System.out.print("日期:"+item.get("openTime") + "\n");
        }

        Map durationMap = new HashMap<>();

        List durationList = new ArrayList<>();//机器持续开机时间集合
        List monthList = new ArrayList<>();//机器开机时间月份集合
   
        Map> listMap = AnalyzeList.stream().collect(Collectors.groupingBy(e -> e.get("openTime")));
        // listMap.entrySet().stream().sorted(Comparator.comparing(Map.Entry.comparingByKey()));
        for ( Map.Entry> entry : listMap.entrySet() ){
            System.out.println("Key(日期):{" + entry.getKey() +"}" + "\t 该日期数据数量:{" + entry.getValue().size() +"}");
            List entryValue = new ArrayList<>();
            entryValue = entry.getValue();
            double duration = entryValue.stream().mapToDouble(k -> Double.parseDouble(k.get("duration").toString())).sum();
            System.out.print("日期:" + entry.getKey() + "\t");
            System.out.println("开机持续时间:" + duration);
            monthList.add(entry.getKey());//收集月份数据
            durationList.add(duration);
        }

        durationMap.put("month",monthList);
        durationMap.put("duration",durationList);
        System.out.println("===============页面需要数据=================");
        for (Map.Entry entry : durationMap.entrySet()){
            System.out.println("月份:" + entry.getKey());
            System.out.println("机器持续开机时间:" + entry.getValue());
        } 
  

 es查询到的信息,通过月份分组后

Java Stream之Collectors.groupingBy分组导致顺序无序问题_第1张图片

 导致后续数据顺序出现无序问题

解决方案:为了保持原有顺序可以指定LinkedHashMap来存放数据

Map> listMap = AnalyzeList.stream()
.collect(Collectors.groupingBy(e -> e.get("openTime"),
LinkedHashMap::new, Collectors.toList()));

 结果保持顺序一致Java Stream之Collectors.groupingBy分组导致顺序无序问题_第2张图片

 

你可能感兴趣的:(java,jvm,开发语言)