Stream
jdk8 adds a new feature of Stream, which can run or calculate the data in the data source.
Note:
- Array | set can be used as the data source for storing data. Stream cannot store data. It can only calculate the data in the data source to get a new result or a new stream
- stream does not affect the data in the data source
- stream is disposable and cannot be used again after being used once
- stream is characterized by delayed loading, that is, when some operations are performed, if there is no termination behavior, intermediate operations will not be performed, and will be performed uniformly when the termination behavior is performed
Use steps:
- Get stream from data source
- Intermediate operation
- Termination behavior
The classes used in this article are Student classes, and the code is as follows:
//Define the Student class to implement the internal comparator public class Student implements Comparable<Student>{ private int id; private String name; private int age; public Student() { } public Student(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return id == student.id && age == student.age && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(id, name, age); } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } //Override compareTo method @Override public int compareTo(Student o) { return this.getAge()-o.getAge(); } }
1. Intermediate operation
1.1 screening and slicing
- filter(): filter information
- limit(n): take the first n
- skip(n): skip the nth
- distinct(): de duplication, which is determined by rewriting Hashcode() and equals() methods
code:
import java.util.List; import java.util.Objects; import java.util.stream.Stream; public class StreamDemo01 { public static void main(String[] args) { List<Student> list = List.of( new Student(101,"Zhang San",19), new Student(102,"Li Si",17), new Student(103,"Wang Wu",25), new Student(104,"Zhao Liu",22), new Student(101,"Zhang San",19)); Stream<Student> stream1 = list.stream(); //Find students older than 17 stream1.filter(student -> { System.out.println("Select age>17 Year old student"); return student.getAge()>17; }).forEach(System.out::println); Stream<Student> stream2 = list.stream(); //Find the first three students over the age of 17 stream2.filter(student -> { System.out.println("Select age>17 Year old student"); return student.getAge()>17; }).limit(3).forEach(System.out::println); //Find students older than 17 and skip the first one Stream<Student> stream3 = list.stream(); stream3.filter(student -> { System.out.println("Select age>17 Year old student"); return student.getAge()>17; }).skip(1).forEach(System.out::println); //Find students older than 17 and remove the weight Stream<Student> stream4 = list.stream(); stream4.filter(student -> { System.out.println("Select age>17 Year old student"); return student.getAge()>17; }).distinct().forEach(System.out::println); } }
1.2 sorting
Using the sort() method, the internal comparator is used by default. If you want to use the external comparator, it needs to be defined.
code:
public class StreamDemo02 { public static void main(String[] args) { List<Student> list = List.of( new Student(101,"Zhang San",19), new Student(102,"Li Si",17), new Student(104,"Wang Wu",25), new Student(103,"Zhao Liu",22), new Student(101,"Zhang San",19)); //Sort in ascending order by id (using external comparator) Stream<Student> stream1 = list.stream(); stream1.sorted((o1,o2)->o1.getId()-o2.getId()).forEach(System.out::println); //Sort in ascending order by age (using internal comparator) Stream<Student> stream2 = list.stream(); stream2.sorted().forEach(System.out::println); } }
1.3 map method and flatMap method
- map(): pass each data of stream operation as an abstract parameter in the function interface, get a result according to the specified implementation behavior (lambda), and finally return all the results to a new stream. If each result is a stream, it will eventually return a new stream that stores each stream
- flatMap(): the function is equal to that of map. The characteristic is that each data must return a stream, which will eventually be combined into an entire stream
code:
import java.util.List; import java.util.stream.Stream; public class StreamDemo03 { public static void main(String[] args) { List<Student> list = List.of( new Student(101,"Zhang San",19), new Student(102,"Li Si",17), new Student(104,"Wang Wu",25), new Student(103,"Zhao Liu",22), new Student(101,"Zhang San",19)); //Get age data Stream<Student> stream1 = list.stream(); stream1.map(o->o.getAge()).forEach(System.out::println); //Get age data Stream<Student> stream2 = list.stream(); stream2.flatMap((s)->Stream.of(s.getAge())).forEach(System.out::println); } }
2. Termination
2.1 reduce method
The reduce() method has three usages, which are shown in the code:
import java.util.List; import java.util.stream.Stream; public class StreamDemo04 { public static void main(String[] args) { List<Student> list = List.of( new Student(101,"Zhang San",19), new Student(102,"Li Si",17), new Student(104,"Wang Wu",25), new Student(103,"Zhao Liu",22), new Student(101,"Zhang San",19)); //Obtain the age in the data, add the first age to the second age, and continue to add the second age as the first age (at this time, the second age is the original third age), and so on Stream<Student> stream1 = list.stream(); int result1 = stream1.map(Student::getAge).sorted().reduce((x,y)->x+y).get(); System.out.println(result1);//102 //Obtain the age in the data, add 100 as the first parameter to the first age, and continue to add the second age as the first age. The rest operations are the same as above Stream<Student> stream2 = list.stream(); int result2 = stream2.map(Student::getAge).sorted().reduce(100,(x,y)-> { System.out.println(x+"-->"+y); return x+y; }); System.out.println(result2);//202 //Obtain the age in the data, add 100 to each age, add the first age and the second age in the obtained results, and the remaining operations are the same as those above //Note: when using this usage, the flow must use parallel flow Stream<Student> stream3 = list.parallelStream(); int result3 = stream3.map(Student::getAge).sorted().reduce(100,(x,y)-> { System.out.println(x+"-->"+y); return x+y; },(x,y)->x+y); System.out.println(result3);//602 } }
2.2 find and match
- allMatch(): check whether all elements are matched
- anyMatch(): checks whether at least one element is matched
- noneMatch(): check if all elements are not matched
- findFirst(): returns the first element
- findAny(): returns any element in the current stream
- count(): returns the total number of elements in the stream
- max(): returns the maximum value in the stream
- min(): returns the minimum value in the stream
code:
import java.util.List; import java.util.stream.Stream; public class StreamDemo05 { public static void main(String[] args) { List<Student> list = List.of( new Student(101,"Zhang San",19), new Student(102,"Li Si",17), new Student(104,"Wang Wu",25), new Student(103,"Zhao Liu",22), new Student(101,"Zhang San",19)); //allMatch(): check whether all elements are matched Stream<Student> stream1 = list.stream(); System.out.println(stream1.allMatch(o->o.getAge()>17));//false //anyMatch(): checks whether at least one element is matched Stream<Student> stream2 = list.stream(); System.out.println(stream2.anyMatch(o->o.getAge()==17));//true //noneMatch(): check if all elements are not matched Stream<Student> stream3 = list.stream(); System.out.println(stream3.noneMatch(o->o.getAge()<16));//true //findFirst(): returns the first element Stream<Student> stream4 = list.stream(); System.out.println(stream4.map(Student::getAge).sorted().findFirst().get());//17 //findAny(): returns any element in the current stream Stream<Student> stream5 = list.stream(); System.out.println(stream5.map(Student::getAge).findAny().get()); //count(): returns the total number of elements in the stream Stream<Student> stream6 = list.stream(); System.out.println(stream6.map(Student::getAge).count());//5 //max(): returns the maximum value in the stream Stream<Student> stream7 = list.stream(); System.out.println(stream7.max((o1,o2)->o1.getAge()-o2.getAge()).map(Student::getAge).get());//25 //min(): returns the minimum value in the stream Stream<Student> stream8 = list.stream(); System.out.println(stream8.min((o1,o2)->o1.getAge()-o2.getAge()).map(Student::getAge).get());//17 } }
2.3 collection
- Collectors.toList(): collect all elements in the stream into a List
- Collectors.toSet(): collect all elements in the stream into a Set and delete duplicates
- Collectors.toMap(): collect all the elements in the stream into the Map, and throw an exception when the same key appears
code:
import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class StreamDemo06 { public static void main(String[] args) { List<Student> list = List.of( new Student(101,"Zhang San",19), new Student(102,"Li Si",17), new Student(104,"Wang Wu",25), new Student(103,"Zhao Liu",22), new Student(101,"Zhang San",19)); //Collectors.toList(): collect all elements in the stream into a List Stream<Student> stream1 = list.stream(); stream1.map(Student::getAge).sorted().collect(Collectors.toList()).forEach(System.out::println); //Collectors.toSet(): collect all elements in the stream into a Set and delete duplicates Stream<Student> stream2 = list.stream(); stream2.map(Student::getAge).sorted().collect(Collectors.toSet()).forEach(System.out::println); //Collectors.toMap(): collect all the elements in the stream into the Map, and throw an exception when the same key appears Stream<Student> stream3 = list.stream(); stream3.map(o->o).distinct().collect(Collectors.toMap(Student::getName,Student::getAge)).forEach((s,i)-> System.out.println(s+":"+i)); } }