Stream in Java8 enhances the function of container objects. It focuses on various very convenient and efficient operations on container objects. With the help of the same new Lambda expression, stream API greatly improves programming efficiency and program readability. At the same time, it provides serial and parallel modes for aggregation operations, Concurrent mode can make full use of the advantages of multi-core processors. Generally, it is difficult and error prone to write parallel code, but using stream API can easily write high-performance concurrent programs without writing one line of multi-threaded code.
I think we can regard the flow as a pipeline. This pipeline is a pipeline for processing data. A product passes through the pipeline, and there will be one process after another, just like the intermediate operation of data, such as filtering, sorting the data I don't need, and the final termination operation is that the product comes down from the pipeline, and we can package it uniformly and put it into the warehouse
When we use a Stream, it usually includes three basic steps: obtaining a data source - "data transfer" - performing data operations to obtain the desired results. Each time the original Stream object is converted, a new Stream object is returned (there can be multiple conversions), which allows its operations to be arranged in a chain like manner and become a pipe, as shown in the following figure:
Stream has several characteristics:
- stream does not store data, but calculates the data according to specific rules
- stream does not change the data source and usually produces a new set or a value
- stream has the characteristic of delayed execution, and the intermediate operation will be executed only when the terminal operation is called
1. Creation of stream
(1) A Stream can be created from a collection array
- Using the java.util.Collection.stream() method to create a stream from a collection, we found that
default Stream<E> stream(){ return StreamSupport.stream(spliterator,false); }
List<String> list = Arrays.asList("a","b","c"); // Create a sequential flow Stream<String> stream = list.stream(); // Create a parallel stream Stream<String> parallelStream = list.parallelStream(); // Merge two flows Stream<String> concat = Stream.concat(list, stream);
(2) Use the Java. Util. Arrays. Stream (t [] array) method to create a stream from an array
int [] array = {1,3,5,6,8}; IntStream stream = Arrays.stream(array);
(3) Static method using Stream: of()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
2. Termination of stream
In order to facilitate our subsequent use, we first initialize some data
public class Person { private String name; // full name private int salary; // salary private int age; // Age private String sex; //Gender private String area; // region public Person(String name, int salary, int age, String sex, String area) { this.name = name; this.salary = salary; this.age = age; this.sex = sex; this.area = area; } public Person(){ } getting,setting and toString()Omit..
To initialize the data, we design a simple set and a complex set
public class lamdaTest { List<Person> personList = new ArrayList<Person>(); List<Integer> simpleList = Arrays.asList(15,22,9,11,33,52,14); @Before public void initData(){ personList.add(new Person("Zhang San",3000,23,"male","Taiyuan")); personList.add(new Person("Li Si",7000,34,"male","Xi'an")); personList.add(new Person("Wang Wu",5200,22,"female","Taiyuan")); personList.add(new Person("Xiao Hei",1500,33,"female","Shanghai")); personList.add(new Person("Dog",8000,44,"female","Beijing")); personList.add(new Person("Iron egg",6200,36,"female","Nanjing")); }
(1) Traverse / match (foreach/find/match)
@Test public void foreachTest(){ // Traverse print set elements simpleList.stream().forEach(System.out::println); // In fact, it can simplify the operation simpleList.forEach(System.out::println); } // Find elements @Test public void findTest(){ // Get any element Optional<Integer> any = simpleList.stream().findAny(); // Get the first element Optional<Integer> first = simpleList.stream().findFirst(); // Print if the element exists any.ifPresent(System.out::println); /** * In a single threaded environment, any and first actually get the same data. findAny() is used for more efficient performance. * If there is less data, the first result is generally returned in serial, but in multi-threaded environment * stream The stream will be truncated and divided into several parts, so the data obtained by each thread may be different, */ // Multithreading environment Optional<Integer> firstMore = simpleList.parallelStream().findFirst(); firstMore.ifPresent(System.out::println); Optional<Integer> anyMore = simpleList.parallelStream().findAny(); anyMore.ifPresent(System.out::println); } // Matching element @Test public void MatchTest(){ // Is everyone's salary greater than 8k boolean b = personList.stream().allMatch(p -> p.getSalary() > 5000); System.out.println(b); // Is someone's salary more than 5000 boolean flag = personList.stream().anyMatch(person -> person.getSalary() > 5000); System.out.println(flag); }
(3) Statistics (count/averaging/sum/max/min)
// Statistics (count/averaging/sum/max/min) @Test public void test(){ // How many objects are there in the statistics collection long count = personList.stream().count(); System.out.println(count); // average age OptionalDouble average = simpleList.stream().mapToInt(i -> i).average(); average.ifPresent(System.out::println); // Sum int sum = IntStream.of(1, 2, 3, 4, 5).sum(); System.out.println(sum); // Finding the maximum value of new Random().ints() will generate a Stream stream containing 20 numbers OptionalInt max = new Random().ints(20).max(); // max.ifPresent(System.out::println); // max.ifPresent(new IntConsumer() { // @Override // public void accept(int value) { // System.out.println(value); // } // }); max.ifPresent(value -> System.out.println(value)); // Find the minimum value OptionalInt min = new Random().ints(20).min(); min.ifPresent(System.out::println); }