Java - 合并两个列表,根据 属性 的值删除重复项

Java - merge two lists removing duplicates based on the value of a property

我有一个 class 这样的:

public class MyObject {
  private Long id;
  private String firstProp;
  private String secondProp;
  private Boolean isLatest;
}

在我的应用程序中,我得到两个列表,一个肯定会设置 isLatestBoolean.TRUEBoolean.FALSE),另一个列表肯定会设置 isLatest 设置为 null

我想要一个 ListSet 的结果,其中包含两个列表中的项目,但删除了 isLatest == null 中的重复项目。也就是说,在删除重复项的同时,我想保留 isLatest != null 所在的元素。重复的定义相同 id.

MyObject中的

equals()hashCode()方法基于idfirstPropsecondProp,不能按原样更改预定义和更改它们会干扰应用程序的其他部分。

List<MyObject> listWithIsLatestSet = list with items below
myObj1 --> id = 1, isLatest = true;
myObj2 --> id = 2, isLatest = false;
myObj3 --> id = 3, isLatest = true;
myObj4 --> id = 4, isLatest = true;

List<MyObject> listWithIsLatestNull = list with items below
myObj5 --> id = 1, isLatest = null;
myObj6 --> id = 2, isLatest = null;
myObj7 --> id = 5, isLatest = null;

结果列表如下所示:

myObj1 --> id = 1, isLatest = true;
myObj2 --> id = 2, isLatest = false;
myObj3 --> id = 3, isLatest = true;
myObj4 --> id = 4, isLatest = true;
myObj7 --> id = 5, isLatest = null;

可以请教一下吗?

这对我有用

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MAIN {

    public static void main(String[] args) {
        Set<MyObject> setWithIsLatestSet = getSetWithIsLatestSet();
        Set<MyObject> setWithIsLatestNull = getSetWithIsLatestNull();
        setWithIsLatestSet.addAll(setWithIsLatestNull);
        setWithIsLatestSet.forEach(System.out::println);
    }

    private static Set<MyObject> getSetWithIsLatestSet() {
        MyObject obj1 = MyObject.builder().id(new Long(1)).isLatest(Boolean.TRUE).build();
        MyObject obj2 = MyObject.builder().id(new Long(2)).isLatest(Boolean.FALSE).build();
        MyObject obj3 = MyObject.builder().id(new Long(3)).isLatest(Boolean.TRUE).build();
        MyObject obj4 = MyObject.builder().id(new Long(4)).isLatest(Boolean.TRUE).build();
        MyObject obj5 = MyObject.builder().id(new Long(5)).isLatest(Boolean.TRUE).build();

        return Stream.of(obj1, obj2, obj3, obj4, obj5).collect(Collectors.toCollection(HashSet::new));
    }

    private static Set<MyObject> getSetWithIsLatestNull() {
        MyObject obj1 = MyObject.builder().id(new Long(1)).build();
        MyObject obj2 = MyObject.builder().id(new Long(2)).build();
        MyObject obj6 = MyObject.builder().id(new Long(6)).build();
        MyObject obj7 = MyObject.builder().id(new Long(7)).build();

        return Stream.of(obj1, obj2, obj6, obj7).collect(Collectors.toCollection(LinkedHashSet::new));
    }
}

@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Getter
@Builder
@ToString
class MyObject {
    @EqualsAndHashCode.Include
    private Long id;
    private Boolean isLatest;
}

输出:

MyObject(id=5, isLatest=true)

MyObject(id=6, isLatest=null)

MyObject(id=7, isLatest=null)

MyObject(id=1, isLatest=true)

MyObject(id=2, isLatest=false)

MyObject(id=3, isLatest=true)

MyObject(id=4, isLatest=true)

你可以试试这个。你的例子工作得很好,

BinaryOperator<MyObject> mergeFunction = (old, lst) -> {
    if (lst.getLatest() != null && lst.getLatest()) {return lst;}
    else if (old.getLatest() == null && lst.getLatest() == null) {return lst;}
    else if (old.getLatest() == null && lst.getLatest() != null && !lst.getLatest()) {return lst;}
    else {return old;}
};

List<MyObject> collect = new ArrayList<>(Stream.concat(listWithIsLatestSet.stream(), listWithIsLatestNull.stream())
        .collect(Collectors.toMap(MyObject::getId, Function.identity(), mergeFunction))
        .values());