I have a stream of objects and I would like to find the one with a maximal value of some attribute that\'s expensive to calculate.
As a specific simple example, say
Here's a variant using an Object[]
as a tuple, not the prettiest code but concise
String coolestString = stringList
.stream()
.map(s -> new Object[] {s, coolnessIndex(s)})
.max(Comparator.comparingInt(a -> (int)a[1]))
.map(a -> (String)a[0])
.orElse(null);
How about using two streams, one to create a map with the pre-calculated values and a second using the map's entry set to find the max value:
String coolestString = stringList
.stream()
.collect(Collectors.toMap(Function.identity(), Test::coolnessIndex))
.entrySet()
.stream()
.max((s1, s2) -> Integer.compare(s1.getValue(), s2.getValue()))
.orElse(null)
.getKey();
just create your (object,metric) pairs first:
public static <T> Optional<T> maximizeOver(List<T> ts, Function<T,Integer> f) {
return ts.stream().map(t -> Pair.pair(t, f.apply(t)))
.max((p1,p2) -> Integer.compare(p1.second(), p2.second()))
.map(Pair::first);
}
(those are com.googlecode.totallylazy.Pair's)