具有多个属性的Java流
流中有以下对象:
class Foo{
String a;
String b;
int c;
}
我想根据以下条件过滤视频流:
I would like to filter a stream based on following criteria:
例如流中有条目:foo1
和foo2
:
foo1
和foo2
的a
和b
值相同,但是c
属性不同.
foo1
and foo2
have same values for a
and b
, but they differ in c
property.
在这种情况下,我希望删除那些c
更高的条目.
I would like to get rid of entries that have c
higher in such case.
在语义上等同于 Eugene的答案,但有点更简单:
Semantically equivalent to Eugene’s answer, but a bit simpler:
List<Foo> foos = Stream.of(new Foo("a", "b", 1), new Foo("a", "b", 2),
new Foo("a", "b", 3), new Foo("a", "bb", 3), new Foo("aa", "b", 3))
.collect(Collectors.collectingAndThen(
Collectors.toMap(x -> Arrays.asList(x.getA(), x.getB()), x -> x,
BinaryOperator.minBy(Comparator.comparing(Foo::getC))),
map -> new ArrayList<>(map.values())));
您需要按同时具有这两个属性的键进行分组,并且由于缺少标准的Pair
类型,因此可以使用具有两个元素的List
或Map.Entry
,两者都可以工作.但是使用List
更简单(在Java 9中,您会使用List.of(…, …)
甚至更简单)并且如果两个属性中可能出现相同的值,则哈希码更好.
You need to group by a key holding both properties and due to the absence of a standard Pair
type, you may use a List
with two elements or a Map.Entry
, both work. But using List
is simpler (in Java 9, you would use List.of(…, …)
which is even simpler) and has a better hash code if the same values may occur in both properties.
当dowstream操作纯粹是简化操作时(例如选择C
属性的最小值),toMap
收集器更适合,因为它不需要处理Optional
.
When the dowstream operation is a pure reduction, like selecting the minimum of the C
property, the toMap
collector fits better as it doesn’t require dealing with Optional
.