我有这堂课:
class A{
int count=0;
//equals and hashCode implemented
}
创建两个集合:
Collection<A> collection1;//something
Collection<A> collection2;//something
连接集合:
Stream.concat(collection1.stream(), collection2.stream())
//do something here???
.distinct()
.sorted(new Comparator<A>() {
@Override
public int compare(A o1, A o2) {
return new Integer(o1.count).compareTo(new Integer(o2.count));
}
})
.collect(Collectors.toList());
我想合并这两个列表,如果有任何重复,我想更新整数count;
以上代码完全摆脱重复
例如,
假设我们在collection1和collection2中都有一个等于(o1.equals(o2) == true)
的对象。一个人有count=10
而另一个人有count=20
我想拥有一个不同对象的集合,该对象包含count=30
有办法吗?
答案 0 :(得分:3)
您无法使用当前的方法,而是可以使用toMap
收集器:
Stream.concat(collection1.stream(), collection2.stream())
.collect(Collectors.toMap(Function.identity(),Function.identity(),
(left, right) -> {
left.setCount(left.getCount() + right.getCount());
return left;
})).values()
.stream()
.sorted(Comparator.comparingInt(A::getCount))
.collect(Collectors.toList());
这使用Stream.concat将collection1
和collection2
合并为一个Stream<A>
。
然后我们调用toMap收集器,其中第一个Function.identity()选择源的元素作为键A
,第二个Function.identity()也选择元素来源作为价值观;再次A
,所以此时,您可以将数据可视化为Map<A, A>
。
函数(left, right) -> { ... }
被称为合并函数,这是两个给定对象相等的地方,然后我们说取第一个元素的计数并取第二个元素的计数,将它们加在一起并将新值分配给我们要保留的其中一个元素,然后丢弃另一个元素。
因为您已覆盖equals
和hashcode
,我们不需要明确地调用它,而是equals
方法将被称为隐式以确定两个给定的对象是否相等。
一旦我们将元素收集到Map<A, A>
,我们就会调用values()
方法来检索Collection<A>
,这样我们就可以使用它创建一个流stream()
方法进一步使我们能够使用已排序的方法对流元素进行排序,最后使用toList收集器将其收集到List<A>
。