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 average
, sum
, min
, max
, 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 thecollect
operation, it creates instances of the result container. In this example, it is a new instance of theAverager
class.accumulator
: The accumulator function incorporates a stream element into a result container. In this example, it modifies theAverager
result container by incrementing thecount
variable by one and adding to thetotal
member 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 anAverager
result container by incrementing thecount
variable by thecount
member variable of the otherAverager
instance and adding to thetotal
member variable the value of the otherAverager
instance'stotal
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