Sefa Taşcan
Sefa Taşcan

Reputation: 11

How to filter a List with objects of two different classes and compare them by fields?

I have two different lists. 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 this:

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

But I want to compare two Lists, and I want to find noncontains value like this:

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

How can I filter with the Java Stream API or any third-party libraries?

Upvotes: 0

Views: 1093

Answers (3)

Milgo
Milgo

Reputation: 2777

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

Upvotes: 0

Ali Ben Zarrouk
Ali Ben Zarrouk

Reputation: 2018

noneMatch helps you here.

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

Upvotes: 1

Youcef LAIDANI
Youcef LAIDANI

Reputation: 60046

You can create a list of ObjectOne from the list of ObjectTwo as this:

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:

listOne.retainAll(objectOne);

if you wont modify the list of ObjectOne, then you can create a second list from listOne

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

Note, this solution need to use hashcode and equals in ObjectOne.

Upvotes: 1

Related Questions