java - How to efficiently compute the maximum value of a collection after applying some function -


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