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
You can utilize the idea of collecting the results from the stream appropriately. The constraint of expensive coolness calculation function makes you consider calling that function exactly once for each element of the stream.
Java 8 provides the collect
method on the Stream
and a variety of ways in which you can use collectors. It appears that if you used the TreeMap
to collect your results, you can retain the expressiveness and at the same time remain considerate of efficiency:
public class Expensive {
static final Random r = new Random();
public static void main(String[] args) {
Map.Entry e =
Stream.of("larry", "moe", "curly", "iggy")
.collect(Collectors.toMap(Expensive::coolness,
Function.identity(),
(a, b) -> a,
() -> new TreeMap<>
((x, y) -> Integer.compare(y, x))
))
.firstEntry();
System.out.println("coolest stooge name: " + e.getKey() + ", coolness: " + e.getValue());
}
public static int coolness(String s) {
// simulation of a call that takes time.
int x = r.nextInt(100);
System.out.println(x);
return x;
}
}
This code prints the stooge
with maximum coolness and the coolness
method is called exactly once for each stooge
. The BinaryOperator
that works as the mergeFunction
((a, b) ->a
) can be further improved.