合并Java 8中的两个对象列表

我有一个Parent带有20个属性的Java(attrib1, attrib2 ..

attrib20)及其相应的getter和setters。我也有两个Parent对象列表:list1list2

现在,我想合并两个列表,并避免基于attrib1和的重复对象attrib2

使用Java 8:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())

.distinct()

.collect(Collectors.toList());

但是我必须在哪里指定属性?我应该重写hashCodeequals方法吗?

回答:

如果要实现equalsand hashCode,则 内部 进行操作Parent。在该类中添加类似的方法

    @Override

public int hashCode() {

return Objects.hash(getAttrib1(), getAttrib2(), getAttrib3(),

// …

getAttrib19(), getAttrib20());

}

@Override

public boolean equals(Object obj) {

if(this==obj) return true;

if(!(obj instanceof Parent)) return false;

Parent p=(Parent) obj;

return Objects.equals(getAttrib1(), p.getAttrib1())

&& Objects.equals(getAttrib2(), p.getAttrib2())

&& Objects.equals(getAttrib3(), p.getAttrib3())

// …

&& Objects.equals(getAttrib19(), p.getAttrib19())

&& Objects.equals(getAttrib20(), p.getAttrib20());

}

如果您这样做了,distinct()在上调用Stream<Parent>将自动执行正确的操作。


如果您不想(或无法)更改类Parent,则没有平等的委托机制,但是您可以求助于 排序, 因为它具有委托机制:

Comparator<Parent> c=Comparator.comparing(Parent::getAttrib1)

.thenComparing(Parent::getAttrib2)

.thenComparing(Parent::getAttrib3)

// …

.thenComparing(Parent::getAttrib19)

.thenComparing(Parent::getAttrib20);

这将基于属性定义顺序。它要求属性本身的类型是可比较的。如果你有这样的定义,你可以用它来实现的等效distinct(),基于这样Comparator

List<Parent> result = Stream.concat(list1.stream(), list2.stream())

.filter(new TreeSet<>(c)::add)

.collect(Collectors.toList());

如果您想将其与并行流一起使用,则还有一个线程安全的变体:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())

.filter(new ConcurrentSkipListSet<>(c)::add)

.collect(Collectors.toList());

以上是 合并Java 8中的两个对象列表 的全部内容, 来源链接: utcz.com/qa/406373.html

回到顶部