我有以下代码:

List<MyObject> filteredObjects = myObjects.stream()
    .filter(anObject -> 
        Collections.frequency(myObjects, anObject) > 1
    )
    .collect(Collectors.toList());

它的工作是从MyObject中的第Collectionmore than once中获取对象.

我需要修改这段代码,以便它为我提供相互匹配的对象,而不是根据equals(),而是基于subset of properties.

因此,如果MyObject具有以下属性:foobarbaz.

public static class MyObject {
    private Foo foo;
    private Bar bar;
    private Baz baz;
    
    // constructor, getters, etc.
}

我希望获取集合中具有相同值foobar的相应对象的对象.

推荐答案

您可以创建包含这些属性(foobar)的自定义对象,这些属性需要使用诸如key之类的对象来匹配和生成辅助Map.

在下面的代码中,为了简明起见,我使用Java 16 record来定义key,如果您使用的是较早的JDK版本,则可以用类替换它.

record Key(Object foo, Object bar) {
    public Key(MyObject o) {
        this(o.getFoo(), o.getBar());
    }
}

当您有一个贴图,将具有相同属性集和相同关键点的所有对象关联在一起时,剩下的唯一事情就是过滤大小大于1的值.

List<MyObject> filteredObjects = myObjects.stream()
    .collect(Collectors.groupingBy( // creates an intermediate Map<Key, List<MyObject>>
        Key::new
    ))
    .values().stream()               // Stream<List<MyObject>>
    .filter(list -> list.size() > 1)
    .flatMap(List::stream)           // Stream<MyObject>
    .toList();                       // for Java 16+ or collect(Collectors.toList()) for earlier versions

如果您需要保留对象的相遇顺序,您可以使用另一个版本的收集器groupingBy(),它允许指定mapFactory:

Collectors.groupingBy(
    Key::new,
    LinkedHashMap::new,
    Collectors.toList()
)

Java相关问答推荐

Mongo DB Bson和Java:在子文档中添加和返回仅存在于父文档中的字段?

如何使用Java API在Oracle ODI中运行模拟?

如何在访问完所有文件后加入所有线程?

在spring—data中自动发现native—sql查询期间遇到重复的SQL别名[id]

多个Java线程和TreeMap.put()的非预期行为

使用@MappdSuperClass扩展ParentClass&Won t继承ParentClass属性

对于几乎不涉及逻辑的请求,您是否应该使用命令模式?

连接Quarkus中的两个异步操作

SpringBoot+Java 17@Valid未验证POJO

带有Health Check的Spring Boot BuildPack打破了本机映像构建过程

如何在我的世界中为互动增加冷却时间?

垃圾收集时间长,会丢弃网络连接,但不会在Kubernetes中反弹Pod

Spring Boot中的应用程序.properties文件中未使用的属性

寻找Thread.sky()方法的清晰度

在一行中检索字符分隔字符串的第n个值

如何通过Java java.lang.Foreign API访问本机字节数组

在Oracle中调用输出参数在索引处缺少IN或OUT参数的函数

原始和参数化之间的差异调用orElseGet时可选(供应商)

Java方法参数:括号中的类型声明?

如何转换Vector<;对象>;转换为int?