【问题标题】:Java Stream - Create a Map of Sorted DuplicatesJava Stream - 创建排序重复的映射
【发布时间】:2021-03-08 18:01:20
【问题描述】:

我有一个对象列表,其中一些对象共享相似的 ID,但其余属性不同。我知道如何按相似的 ID 对它们进行分组...

...
.stream()
.collect(groupingBy(obj -> obj.id, mapping(obj -> obj, toList())));

但是我想添加一个额外的逻辑层。我希望Map 中的每个List 按两个条件排序。

第一个条件,我想使用contains 检查obj.specialId 是否存在于单独的Set 中。如果不是,那很好,但如果是,那么我希望该对象在Set 中排在第一位。类似specialSet.contains(obj.specialId)

第二个条件是我想让它们按日期排序。这些对象有一个名为日期的属性obj.date

条件并不重要,我最困惑的是如何保持Map 中值的顺序。一旦我知道该怎么做,添加我想要的条件应该很容易。

【问题讨论】:

    标签: java java-stream grouping


    【解决方案1】:

    据我了解,您需要从使用 set 切换到使用 list 才能保持元素之间的顺序。然后你需要三个基本的代码:

    1. 像这样的 lambda 分类器:Thing::getId,这意味着使用 id 对它们进行分组。
    2. 数据结构的供应商表达式,映射是最简单的方法:HashMap::new
    3. 用于处理分组元素的收集器,例如 Collectors.collectingAndThen(...)

    一个完整的例子:

    public class Sandbox {
    
    
        public static <T> List<T> doThingWithList( List<T> list) {
            /**
             * Do some fancy things on your grouped elements
             * Such as sorting them
             */
            return list;
        }
    
        public static void main(String[] args){
            List<Thing> things = new ArrayList<>();
            things.add(new Thing(1,"first", "first ever"));
            things.add(new Thing(2,"second", "almost got first place"));
            things.add(new Thing(2,"second","sharing the second place is better than finishing third"));
    
            Map<Integer,List<Thing>> result = things.stream()
                    .collect(
                            Collectors.groupingBy(Thing::getId, HashMap::new,
                                    Collectors.collectingAndThen(Collectors.toList(), Sandbox::doThingWithList))
                    );
            System.out.println(result);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-01
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多