Java Stream: find an element with a min/max value of an attribute

后端 未结 9 1752
梦毁少年i
梦毁少年i 2020-12-06 15:58

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

9条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-06 16:32

    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.

提交回复
热议问题