合并Java 8中的两个对象列表
我有一个Parent
带有20个属性的Java类(attrib1, attrib2 ..
attrib20)及其相应的getter和setters。我也有两个Parent
对象列表:list1
和list2
。
现在,我想合并两个列表,并避免基于attrib1
和的重复对象attrib2
。
使用Java 8:
List<Parent> result = Stream.concat(list1.stream(), list2.stream()) .distinct()
.collect(Collectors.toList());
但是我必须在哪里指定属性?我应该重写hashCode
和equals
方法吗?
回答:
如果要实现equals
and 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