How to get multiple values from an object using a single stream operation?

前端 未结 5 1291
梦如初夏
梦如初夏 2020-12-10 05:45

I want to determine the minimum area required to display a collection of points. The easy way is to loop through the collection like this:

int minX = Integer         


        
5条回答
  •  时光取名叫无心
    2020-12-10 06:45

    Thanks everyone for all the suggestions and answers. This is very helpful and I learned a lot!

    I decided to give most of your solutions a go (except for the JDK12 solution). For some of them you already provide me with the code. In addition, I made my own Collector.

    class extremesCollector implements Collector, Map> {
    
        @Override
        public Supplier> supplier() {
            Map map = new HashMap<>();
            map.put("xMin", Integer.MAX_VALUE);
            map.put("yMin", Integer.MAX_VALUE);
            map.put("xMax", Integer.MIN_VALUE);
            map.put("yMax", Integer.MIN_VALUE);
            return () -> map;
        }
    
        @Override
        public BiConsumer, Point> accumulator() {
            return (a, b) -> {
                a.put("xMin", Math.min(a.get("xMin"), b.x));
                a.put("yMin", Math.min(a.get("yMin"), b.y));
                a.put("xMax", Math.max(a.get("xMax"), b.x));
                a.put("yMax", Math.max(a.get("yMax"), b.y));
            };
        }
    
        @Override
        public Function, Map> finisher() {
            return Function.identity();
        }
    
        @Override
        public BinaryOperator> combiner() {
            return (a, b) -> {
                a.put("xMin", Math.min(a.get("xMin"), b.get("xMin")));
                a.put("yMin", Math.min(a.get("yMin"), b.get("yMin")));
                a.put("xMax", Math.max(a.get("xMax"), b.get("xMax")));
                a.put("yMax", Math.max(a.get("yMax"), b.get("yMax")));
                return a;
            };
        }
    
        @Override
        public Set characteristics() {
            Set characteristics = new HashSet<>();
            characteristics.add(Characteristics.UNORDERED);
            characteristics.add(Characteristics.CONCURRENT);
            characteristics.add(Characteristics.IDENTITY_FINISH);
            return characteristics;
        }
    }
    

    Results

    I gave all of them a try and compared the results. Good news: for all of them, I got the same result as far as the values are concerned!

    With respect to the speed, here is the ranking:

    1. for-loops
    2. four individual streams
    3. stream with self-made Collector
    4. parallel stream with self-made Collector
    5. statistics approach provided by Andrew Tobilko

    Number 2 and 3 are actually very close in terms of speed. The parallel version is probably slower because my dataset is too small.

提交回复
热议问题