Java 8 Streams: How to call once the Collection.stream() method and retrieve an array of several aggregate values with different fields

后端 未结 3 417
没有蜡笔的小新
没有蜡笔的小新 2021-02-03 11:18

I\'m starting with the Stream API in Java 8.

Here is my Person object I use:

public class Person {

    private String firstName;
    private String last         


        
3条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-03 11:54

    Here is the collector

    public class PersonStatistics {
        private long firstNameCounter;
        private int maxAge = Integer.MIN_VALUE;
        private double minHeight = Double.MAX_VALUE;
        private double totalWeight;
        private long total;
        private final Predicate firstNameFilter;
    
        public PersonStatistics(Predicate firstNameFilter) {
            Objects.requireNonNull(firstNameFilter);
            this.firstNameFilter = firstNameFilter;
        }
    
        public void accept(Person p) {
            if (this.firstNameFilter.test(p)) {
                firstNameCounter++;
            }
    
            this.maxAge = Math.max(p.getAge(), maxAge);
            this.minHeight = Math.min(p.getHeight(), minHeight);
            this.totalWeight += p.getWeight();
            this.total++;
        }
    
        public PersonStatistics combine(PersonStatistics personStatistics) {
            this.firstNameCounter += personStatistics.firstNameCounter;
            this.maxAge = Math.max(personStatistics.maxAge, maxAge);
            this.minHeight = Math.min(personStatistics.minHeight, minHeight);
            this.totalWeight += personStatistics.totalWeight;
            this.total += personStatistics.total;
    
            return this;
        }
    
        public Object[] toStatArray() {
            return new Object[]{firstNameCounter, maxAge, minHeight, total == 0 ? 0 : totalWeight / total};
        }
    }
    

    You can use this collector as follows

    public class PersonMain {
        public static void main(String[] args) {
            List personsList = new ArrayList<>();
    
            personsList.add(new Person("John", "Doe", 25, 180, 80));
            personsList.add(new Person("Jane", "Doe", 30, 169, 60));
            personsList.add(new Person("John", "Smith", 35, 174, 70));
            personsList.add(new Person("John", "T", 45, 179, 99));
    
            Object[] objects = personsList.stream().collect(Collector.of(
                    () -> new PersonStatistics(p -> p.getFirstName().equals("John")),
                    PersonStatistics::accept,
                    PersonStatistics::combine,
                    PersonStatistics::toStatArray));
            System.out.println(Arrays.toString(objects));
        }
    }
    

提交回复
热议问题