Large data item 2 (Java8 polymerization operation)

Introduction: For a good understanding of these methods, you need to be familiar with the use of java8 properties and methods cited Lambda

One: Introduction

  We use a set purpose, more often than not simply just where to save the data. But to search (traverse), or to calculate or set of operations inside .... statistical data. Now suppose I have an entity object Person as follows for testing set operations

public class Person {
    public enum Sex {
        MALE, FEMALE
    }
    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    Person(String nameArg, LocalDate birthdayArg, Sex genderArg, String emailArg) {
        name = nameArg;
        birthday = birthdayArg;
        gender = genderArg;
        emailAddress = emailArg;
    }

    public int getAge() {
        return birthday.until(IsoChronology.INSTANCE.dateNow()).getYears();
    }

    public void printPerson() {
        System.out.println(name + ", " + this.getAge());
    }

    public Sex getGender() {
        return gender;
    }

    public String getName() {
        return name;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    public LocalDate getBirthday() {
        return birthday;
    }

    public static int compareByAge(Person a, Person b) {
        return a.birthday.compareTo(b.birthday);
    }

    public static List<Person> createRoster() {

        List<Person> roster = new ArrayList<>();
        roster.add(new Person("Fred", IsoChronology.INSTANCE.date(1980, 6, 20), Person.Sex.MALE, "[email protected]"));
        roster.add(new Person("Jane", IsoChronology.INSTANCE.date(1990, 7, 15), Person.Sex.FEMALE, "[email protected]"));
        roster.add(
                new Person("George", IsoChronology.INSTANCE.date(1991, 8, 13), Person.Sex.MALE, "[email protected]"));
        roster.add(new Person("Bob", IsoChronology.INSTANCE.date(2000, 9, 12), Person.Sex.MALE, "[email protected]"));

        return roster;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", birthday=" + birthday + ", gender=" + gender + ", emailAddress="
                + emailAddress + "]";
    }
    
}

1.1 pipes and streams

NOTE: the pipe is a ordered polymerization operation (A  Pipeline  IS Aggregate A Sequence of Operations)

For example one: Print set all gender male name

@Test
    public void test1() {
        roster.stream().filter(e -> e.getGender() == Person.Sex.MALE).forEach(e -> System.out.println(e.getName()));
    }

Of course, you can also use for-each loop to do this

Analysis: Pipeline contains those components

   A data source, i.e. a set roster

  Zero or more intermediate operation, the present embodiment only a male .filter filter set.

   A terminating operation, i.e. forEach through and print name, no return value.

Example II: calculate the mean, that is a draw to calculate the age set for men

@Test
    public void test() {
        double average = roster.stream().filter(p -> p.getGender() == Person.Sex.MALE).mapToInt(Person::getAge)
                .average().getAsDouble();
        System.out.println(average);
    }

Polymerization filter -> mapToInt -> average () -> getAsDouble

Two: Restore Operation

Note:The JDK contains many terminal operations (such as averagesumminmax, and count) that return one value by combining the contents of a stream. These operations are called reduction operations.

Restore operation: Personal understood that the restore operation i.e. operation in a certain process or condition of the termination, and converted into another state. Here convection that is terminating operation, and converted to another state (i.e. Double or another state comprises a reference type Int ....)

Here mainly introduce two Stream.reduce and Stream.collect method.

2.1: calculating the sum Stream.reduce

. Method 1: sum () polymerization roster.stream () mapToInt (Person :: getAge) .sum ();

Method two: i.e. by Stream.reduce 

Integer totalAgeReduce = roster.stream().map(Person::getAge).reduce(0, (a, b) -> a + b);

NOTE: 0 Int data can be changed arbitrarily, that is, its role on the basis of the original sum plus 0

2.2: Stream.collect reduction methods into other types

Example a: calculate the mean, is reduced to the specified type Averager

public class Averager implements IntConsumer {
    private int total = 0;
    private int count = 0;

    public double average() {
        return count > 0 ? ((double) total) / count : 0;
    }

    public double getTotal() {
        return total;
    }

    @Override
    public void accept(int i) {
        total += i;
        count++;
    }

    public void combine(Averager other) {
        total += other.total;
        count += other.count;
    }
}

test:

@Test
    public void test3() {
        SupplierImpl impl = new SupplierImpl();
        Averager averageCollect = roster.stream().filter(p -> p.getGender() == Person.Sex.MALE).map(Person::getAge)
                .collect(Averager::new, Averager::accept, Averager::combine);
        System.out.println("Average age of male members: " + averageCollect.average());
        
        Averager averageCollect2 = roster.stream().filter(p -> p.getGender() == Person.Sex.MALE).map(Person::getAge)
                .collect(impl, Averager::accept, Averager::combine);
        System.out.println("Average age of male members22: " + averageCollect2.average());
    }

The collect operation in this example takes three arguments:

  • supplier: The supplier is a factory function; it constructs new instances. For the collect operation, it creates instances of the result container. In this example, it is a new instance of the Averager class.
  • accumulator: The accumulator function incorporates a stream element into a result container. In this example, it modifies the Averager result container by incrementing the count variable by one and adding to the totalmember variable the value of the stream element, which is an integer representing the age of a male member.
  • combiner: The combiner function takes two result containers and merges their contents. In this example, it modifies an Averager result container by incrementing the count variable by the count member variable of the other Averager instance and adding to the total member variable the value of the other Averager instance's total member variable

Example II: Stream.collect method of reduction to List <String>

@Test
    public void test5() {
        List<String> namesOfMaleMembersCollect = roster.stream().filter(p -> p.getGender() == Person.Sex.MALE)
                .map(p -> p.getName()).collect(Collectors.toList());
        namesOfMaleMembersCollect.forEach(System.out::print);
        System.out.println();
        namesOfMaleMembersCollect.add("1234");
        namesOfMaleMembersCollect.forEach(System.out::print);
    }

Example III: Stream.collect method of reduction to Map <Object, List <Object>,

@Test
    public void test6() {
        Map<Sex, List<Person>> byGender = roster.stream().collect(Collectors.groupingBy(Person::getGender));
        Set<Sex> keySet = byGender.keySet();
        for (Sex sex : keySet) {
            List<Person> list = byGender.get(sex);
            System.out.println("sex = " + sex);
            list.forEach(System.out::print);
            System.out.println();
        }
    }

Be used: the source data packets

Example four: Stream.collect method of reduction to Map <Object, List>,

@Test
    public void test7() {
        Map<Person.Sex, List<String>> namesByGender = roster.stream().collect(
                Collectors.groupingBy(Person::getGender, Collectors.mapping(Person::getName, Collectors.toList())));
        Set<Sex> keySet = namesByGender.keySet();
        for (Sex sex : keySet) {
            List<String> list = namesByGender.get(sex);
            System.out.println("sex = " + sex);
            list.forEach(System.out::print);
            System.out.println();
        }
        Map<Person.Sex, List<String>> namesByGender2 = roster.stream().collect(Collectors.groupingBy((p) -> {
            return p.getGender();
        }, Collectors.mapping(Person::getName, Collectors.toList())));
        Set<Sex> keySet2 = namesByGender2.keySet();
        for (Sex sex : keySet2) {
            List<String> list = namesByGender2.get(sex);
            System.out.println("sex = " + sex);
            list.forEach(System.out::print);
            System.out.println();
        }
    }

Example five: Stream.collect method, and summed packet

@Test
    public void test8() {
        Map<Person.Sex, Integer> totalAgeByGender = roster.stream().collect(
                Collectors.groupingBy(Person::getGender, Collectors.reducing(0, Person::getAge, Integer::sum)));
        Set<Sex> keySet2 = totalAgeByGender.keySet();
        for (Sex sex : keySet2) {
            Integer integer = totalAgeByGender.get(sex);
            System.out.println("sex = " + sex);
            System.out.println("年龄sum = " + integer);

        }
    }

Example six: Stream.collect method, and calculate the average packet

 @Test
    public void test9() {
        Map<Person.Sex, Double> averageAgeByGender = roster.stream()
                .collect(Collectors.groupingBy(Person::getGender, Collectors.averagingInt(Person::getAge)));
        Set<Sex> keySet2 = averageAgeByGender.keySet();
        for (Sex sex : keySet2) {
            Double double1 = averageAgeByGender.get(sex);
            System.out.println("sex = " + sex);
            System.out.println("年龄avg = " + double1);
        }
    }        

Three parallel operation (of Parallelism)

 

llll 

Guess you like

Origin www.cnblogs.com/jinliang374003909/p/12067425.html