Man*_*Joy 27 java java-8 java-stream
我有一个Parent
具有20个属性的Java类(attrib1, attrib2 .. attrib20)
及其相应的getter和setter.我还有两个Parent
对象列表:list1
和list2
.
现在我想合并两个列表并避免基于attrib1
和的重复对象attrib2
.
使用Java 8:
List<Parent> result = Stream.concat(list1.stream(), list2.stream())
.distinct()
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
但是我必须在哪个地方指定属性?我应该覆盖hashCode
和equals
方法吗?
Hol*_*ger 24
如果你想实现equals
和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());
}
Run Code Online (Sandbox Code Playgroud)
如果你这样做,distinct()
在一个Stream<Parent>
遗嘱上调用会自动做正确的事情.
如果您不希望(或不能)更改类Parent
,则没有用于相等的委派机制,但您可以使用具有委派机制的排序:
Comparator<Parent> c=Comparator.comparing(Parent::getAttrib1)
.thenComparing(Parent::getAttrib2)
.thenComparing(Parent::getAttrib3)
// …
.thenComparing(Parent::getAttrib19)
.thenComparing(Parent::getAttrib20);
Run Code Online (Sandbox Code Playgroud)
这定义了基于属性的订单.它要求属性本身的类型具有可比性.如果您有这样的定义,您可以使用它来实现等效的a distinct()
,基于Comparator
:
List<Parent> result = Stream.concat(list1.stream(), list2.stream())
.filter(new TreeSet<>(c)::add)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
如果您想将其与并行流一起使用,还有一个线程安全的变体:
List<Parent> result = Stream.concat(list1.stream(), list2.stream())
.filter(new ConcurrentSkipListSet<>(c)::add)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
43211 次 |
最近记录: |