简体   繁体   English

Java Stream - 创建一个 Map 的排序重复

[英]Java Stream - Create a Map of Sorted Duplicates

I have a list of objects and some of these objects share a similar ID, however the rest of the attributes are different.我有一个对象列表,其中一些对象共享相似的 ID,但是属性的 rest 不同。 I know how to group them by similar IDs...我知道如何按相似的 ID 对它们进行分组...

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

However I want to add an extra layer of logic.但是我想添加一层额外的逻辑。 I want each List in the Map to be sorted by two conditions.我希望Map中的每个List都按两个条件排序。

First condition, I want to check whether the obj.specialId exists within a separate Set using contains .第一个条件,我想使用contains检查obj.specialId是否存在于单独的Set中。 If it doesn't, that's fine, but if it does then I want that object to be first in the Set .如果不是,那很好,但如果是,那么我希望 object 在Set中排在第一位。 Something like specialSet.contains(obj.specialId) .类似specialSet.contains(obj.specialId)的东西。

Second condition is that I want to have them sorted by date.第二个条件是我想让它们按日期排序。 The objects have an attribute called date, obj.date .这些对象有一个名为 date 的属性obj.date

The conditions are not really important, what I'm most confused about is how to preserve the order of the values in my Map .条件并不重要,我最困惑的是如何保留Map中值的顺序。 Once I know how to do that, it should be easy to add the conditions I want.一旦我知道如何做到这一点,添加我想要的条件应该很容易。

From what I can understand, you will need to switch from using set to using list to be able to keep the order between the elements.据我了解,您需要从使用 set 切换到使用 list 才能保持元素之间的顺序。 Then you need three basic pieces of code:然后你需要三个基本的代码:

  1. A classifier such as this lambda: Thing::getId , that means using the id to group them.诸如 lambda: Thing::getId类的分类器,这意味着使用 id 对它们进行分组。
  2. A supplier expression for data structure, a map is the easiest way to go: HashMap::new .数据结构的供应商表达式 map 是 go 的最简单方法: HashMap::new
  3. A Collector to work on the grouped elements something like Collectors.collectingAndThen(...)用于处理分组元素的收集器,例如Collectors.collectingAndThen(...)

A complete exemple:一个完整的例子:

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);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM