如何使用Java中具有不同类的两个对象和具有compare字段的列表进行过滤

问题描述

我有两个不同的清单。我想查找并按不在其他列表上的字段进行过滤。例如。

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"}



如果我要过滤一个列表,则使用类似的 org.springframework.cglib.core.CollectionUtils

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

但是我想比较两个List,我想找到像这样的非包含值

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

如何使用streamApi或任何第三方库进行过滤?

解决方法

您可以这样从ObjectOne的列表中创建ObjectTwo的列表:

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

请注意,此解决方案需要在hashcode中使用equalsObjectOne

,

noneMatch在这里为您提供帮助。

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

我不知道如何只用一个流来做到这一点,但至少我有两个解决方案。

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...