I\'m starting with the Stream API in Java 8.
Here is my Person object I use:
public class Person {
private String firstName;
private String last
This is a bit tricky to solve with standard JDK 8 API, which doesn't offer many ways to compose Collector
types. If you're willing to use a third party library like jOOλ, you could write:
Tuple4, Optional, Optional> result =
Seq.seq(personsList)
.collect(
filter(p -> p.getFirstName().equals("John"), count()),
max(Person::getAge),
min(Person::getHeight),
avg(Person::getWeight)
);
System.out.println(result);
The above yields:
(2, Optional[35], Optional[1.8], Optional[75.0])
Note, it's using the new Agg.filter() method, which is similar to the JDK 9 Collectors.filtering()
method and works like this:
public static Collector filter(
Predicate super T> predicate, Collector downstream) {
return Collector.of(
downstream.supplier(),
(c, t) -> {
if (predicate.test(t))
downstream.accumulator().accept(c, t);
},
downstream.combiner(),
downstream.finisher()
);
}
collect(collector1, collector2, ...)
work?If you don't want to use the above third-party library, you can write your own Collector
combining utility. An example that combines two collectors into a Tuple2
collector:
static Collector, Tuple2> collectors(
Collector collector1
, Collector collector2
) {
return Collector., Tuple2>of(
() -> tuple(
collector1.supplier().get()
, collector2.supplier().get()
),
(a, t) -> {
collector1.accumulator().accept(a.v1, t);
collector2.accumulator().accept(a.v2, t);
},
(a1, a2) -> tuple(
collector1.combiner().apply(a1.v1, a2.v1)
, collector2.combiner().apply(a1.v2, a2.v2)
),
a -> tuple(
collector1.finisher().apply(a.v1)
, collector2.finisher().apply(a.v2)
)
);
}
Disclaimer: I work for the company behind jOOλ.