suppose have method computes maximum of collection
tointfunction
:
static <t> void foo1(collection<? extends t> collection, tointfunction<? super t> function) { if (collection.isempty()) throw new nosuchelementexception(); int max = integer.min_value; t maxt = null; (t t : collection) { int result = function.applyasint(t); if (result >= max) { max = result; maxt = t; } } // maxt }
with java 8, translated into
static <t> void foo2(collection<? extends t> collection, tointfunction<? super t> function) { t maxt = collection.stream() .max(comparator.comparingint(function)) .get(); // maxt }
a disadvantage new version function.applyasint
invoked repeatedly same value of t
. (specifically if collection has size n
, foo1
invokes applyasint
n
times whereas foo2
invokes 2n - 2
times).
disadvantages of first approach code less clear , can't modify use parallelism.
suppose wanted using parallel streams and invoke applyasint
once per element. can written in simple way?
you can use custom collector keeps running pair of maximum value , maximum element:
static <t> void foo3(collection<? extends t> collection, tointfunction<? super t> function) { class pair { int max = integer.min_value; t maxt = null; } t maxt = collection.stream().collect(collector.of( pair::new, (p, t) -> { int result = function.applyasint(t); if (result >= p.max) { p.max = result; p.maxt = t; } }, (p1, p2) -> p2.max > p1.max ? p2 : p1, p -> p.maxt )); // maxt }
one advantage creates single pair
intermediate object used through-out collecting process. each time element accepted, holder updated new maximum. finisher operation returns maximum element , disgards maximum value.
Comments
Post a Comment