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())));
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.
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
.