如何在Java中使用比较字段筛选具有不同类的两个对象的列表

huangapple go评论81阅读模式
英文:

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

问题

import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<ObjectOne> objectOneList = ...; // Initialize your ObjectOne list
        List<ObjectTwo> objectTwoList = ...; // Initialize your ObjectTwo list

        // Find and filter by field not on the other list using Java Stream API
        List<ObjectOne> filteredObjectOneList = objectOneList.stream()
                .filter(objectOne -> objectTwoList.stream()
                        .noneMatch(objectTwo -> objectOne.getId() == objectTwo.getXId()
                                && objectOne.getName().equals(objectTwo.getText())))
                .collect(Collectors.toList());
    }
}

class ObjectOne {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

class ObjectTwo {
    private int xId;
    private String text;

    public int getXId() {
        return xId;
    }

    public String getText() {
        return text;
    }
}

Please note that the code provided is a Java example of how you can achieve the desired filtering using the Java Stream API. You would need to replace the placeholder comments (...) with actual list instances and make sure that the ObjectOne and ObjectTwo classes are defined with the necessary methods and fields.

英文:

I have two different list. I want to find and filter by field not on the other list. For example.

List&lt;ObjectOne&gt;      List&lt;ObjectTwo&gt;
field | value        field | value
{id=5, name=&quot;aaa&quot;}   {xId=4, text=&quot;aaa&quot;}
{id=6, name=&quot;bbb&quot;}   {xId=6, text=&quot;bbb&quot;}
{id=7, name=&quot;ccc&quot;}   {xId=5, text=&quot;ccc&quot;}



If I want to filter one list, I am using org.springframework.cglib.core.CollectionUtils like that

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

But I want to compare two List, and I want to find noncontains value like that

objectOne = {id=5, name=&quot;aaa&quot;} , {id=7, name=&quot;ccc&quot;}

How am I filter with streamApi or any third-party libraries ?

答案1

得分: 1

你可以根据 ObjectTwo 列表创建一个 ObjectOne 列表,方法如下:

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

然后你可以使用 retainAll 方法来找到共同的元素:

listOne.retainAll(objectOne);

如果你不想修改 ObjectOne 列表,那么你可以从 listOne 创建第二个列表:

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

注意,这个解决方案需要在 ObjectOne 类中使用 hashcodeequals 方法。

英文:

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

List&lt;ObjectOne&gt; objectOne = listTwo.stream()
        .map(x -&gt; 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&lt;ObjectOne&gt; listOne2 = new ArrayList&lt;&gt;(listOne);
listOne2.retainAll(objectOne);

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

答案2

得分: 1

noneMatch 在这里对你有所帮助。

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

noneMatch helps you here.

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

答案3

得分: 0

我不知道如何只使用一个流来完成这个操作,但至少我得到了一个处理两个流的解决方案。

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

I don't know how to do this with just one stream, but at least I got a solution for two.

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

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

huangapple
  • 本文由 发表于 2020年9月11日 17:30:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63844359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定