简体   繁体   English

如何过滤具有不同类的两个对象和Java中的比较字段的列表

[英]How to filter a List with two object of different class and with compare field in Java

I have two different list.我有两个不同的列表。 I want to find and filter by field not on the other list.我想按不在其他列表中的字段查找和过滤。 For example.例如。

List<ObjectOne>      List<ObjectTwo>
field | value        field | value
{id=5, name="aaa"}   {xId=4, text="aaa"}
{id=6, name="bbb"}   {xId=6, text="bbb"}
{id=7, name="ccc"}   {xId=5, text="ccc"}



If I want to filter one list, I am using org.springframework.cglib.core.CollectionUtils like that如果我想过滤一个列表,我会像这样使用org.springframework.cglib.core.CollectionUtils

CollectionUtils.filter(objectOne, s -> (
(ObjectOne) s).getId() == anyObject.getXId()
&&  (ObjectOne) s).getName() == anyObject.getText());

But I want to compare two List, and I want to find noncontains value like that但是我想比较两个 List,我想找到这样的 noncontains 值

objectOne = {id=5, name="aaa"} , {id=7, name="ccc"}

How am I filter with streamApi or any third-party libraries ?我如何使用 streamApi 或任何第三方库进行过滤?

You can create a list of ObjectOne from the list of ObjectTwo as this:您可以创建列表ObjectOne从列表中ObjectTwo就象这样:

List<ObjectOne> objectOne = listTwo.stream()
        .map(x -> new ObjectOne(x.getxId(), x.getText()))
        .collect(Collectors.toList());

And then you can use retainAll to find the common elements:然后你可以使用retainAll来查找公共元素:

listOne.retainAll(objectOne);

if you wont modify the list of ObjectOne , then you can create a second list from listOne如果您不修改ObjectOne的列表,则可以从listOne创建第二个列表

List<ObjectOne> listOne2 = new ArrayList<>(listOne);
listOne2.retainAll(objectOne);

Note, this solution need to use hashcode and equals in ObjectOne .请注意,此解决方案需要在ObjectOne使用hashcodeequals

noneMatch helps you here. noneMatch可以帮助您。

objectOnes.stream()
          .filter(x -> objectTwos.stream()
                                 .noneMatch(y -> y.text.equals(x.name) && y.xId == x.id))
          .collect(Collectors.toList());

I don't know how to do this with just one stream, but at least I got a solution for two.我不知道如何只用一个流来做到这一点,但至少我得到了两个的解决方案。

List<ObjectOne> list1 = new ArrayList<>();
List<ObjectTwo> list2 = new ArrayList<>();
list1.stream()
        .filter(o1 -> isInObjectTwoList(list2, o1))
        .collect(Collectors.toList());

private boolean isInObjectTwoList(List<ObjectTwo> objectTwoList, ObjectOne o1) {
    return objectTwoList.stream()
            .filter(o2 -> o2.getText().equals(o1.getValue()))
            .findAny()
            .isPresent();
}

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

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