overview
There are two very famous improvements in java8, one is Lambda expression and the other is Stream.
Stream is a stream. Its main function is to search and filter Collection data. It is similar to SQL database operation. The difference between stream and Collection is that Collection is only responsible for storing data, not for other data processing, mainly dealing with memory. But stream is mainly responsible for calculating data, mainly dealing with CPU.
Stream syntax explanation
The Stream execution process is very simple. There are three main processes. First, create a Stream, then use the Stream to operate data, and finally terminate the Stream. It's a bit like the life cycle of a Stream.
@Data public class Student { private Integer id; private String name; private Integer age; private Double score; Student(Integer id, String name, Integer age, Double score){ this.id = id; this.name = name; this.age = age; this.score = score; } }
1. Create a Stream
Create Stream from collection
public class StreamTest { public static List<Student> getStudents() { List<Student> students = new ArrayList<>(); students.add(new Student(1, "petty thief", 10, 90.0)); students.add(new Student(2, "Xiao Zhang", 12, 95.0)); students.add(new Student(3, "Xiao Wang", 15, 85.0)); return students; } public static void main(String[] args) { //Returns a sequence flow Stream<Student> stream1 = getStudents().stream(); //Return a parallel stream Stream<Student> stream2 = getStudents().parallelStream(); } }
Create a Stream from an array
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7}; IntStream intStream = Arrays.stream(arr);
Through Stream.of
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6); Stream<String> stringStream = Stream.of("1", "2", "3", "4", "5", "6"); Stream<Student> studentStream = Stream.of(new Student(1, "petty thief", 10, 90.0), new Student(2, "Xiao Zhang", 12, 95.0), new Student(3, "Xiao Wang", 15, 85.0));
Create an infinite flow
//Every 5 numbers, starting from 0, infinite loop Stream.iterate(0, t -> t+5).forEach(System.out::println); //Take one every 5 numbers, starting from 0, only take 5 numbers Stream.iterate(0, t -> t+5).limit(5).forEach(System.out::println); //Take a random number Stream.generate(Math::random).limit(5).forEach(System.out::println);
2. Use Stream to operate data
Filtering and slicing
//Filtering: filtering students older than 12 getStudents().stream().filter(item -> item.getAge() > 12).forEach(System.out::println); //Cut off flow: screen out the top 2 students getStudents().stream().limit(2).forEach(System.out::println); //Skip element: skip the first 2 elements getStudents().stream().skip(2).forEach(System.out::println); //Filter repeating elements getStudents().stream().distinct().forEach(System.out::println);
mapping
//map operation List<String> list = Arrays.asList("java", "python", "c++"); Stream<String> stream = list.stream(); //In this case, each lowercase letter has an uppercase letter mapping stream.map(str -> str.toUpperCase()).forEach(System.out::println); //Filter out all the students of all ages, and then filter out the students of over 12 ages Stream<Student> stream = getStudents().stream(); Stream<Integer> ageStream = stream.map(Student::getAge); ageStream.filter(age -> age > 12).forEach(System.out::println);
sort
//Natural order List<Integer> list = Arrays.asList(1, 3,24, 5, 6, 8, 23, 45, 72, 16); Stream<Integer> stream = list.stream(); stream.sorted().forEach(System.out::println); //Object sorting: object sorting can implement the comparable interface first or directly specify List<Student> studentList = getStudents(); //Implement the comparable interface studentList.stream().sorted().forEach(System.out::println); //Direct designation studentList.stream().sorted((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())).forEach(System.out::println);
3. Terminate Stream
Match and find
List<Student> list = getStudents(); //Judge whether all students are older than 12 boolean allMatch = list.stream().allMatch(item -> item.getAge() > 12); //Determine if there are students older than 12 boolean anyMatch = list.stream().anyMatch(item -> item.getAge() > 20); //Judge whether there is a student named "Xiao Li" boolean noneMatch = list.stream().noneMatch(item -> item.getName().equals("petty thief")); //Find the first student Optional<Student> first = list.stream().findFirst(); //Find student data long count = list.stream().count(); long count1 = list.stream().filter(item -> item.getScore() > 90).count(); //Find elements in the current flow Optional<Student> any = list.stream().findAny(); //Find the highest score of students: if students implement the comparable interface, they can directly compare Stream<Double> doubleStream = list.stream().map(item -> item.getScore()); doubleStream.max(Double::compareTo);
reduction
List<Integer> list = Arrays.asList(1, 3,24, 5, 6, 8, 23, 45, 72, 16); //Calculate the sum of the totals list.stream().reduce(0, Integer::sum); //Calculate the total score of students List<Student> students = getStudents(); Stream<Double> stream = students.stream().map(Student::getScore); stream.reduce(Double::sum);
collect
//Return a list List<Student> list = getStudents().stream().filter(e -> e.getAge() > 12).collect(Collectors.toList()); //Return a set Set<Student> set = getStudents().stream().filter(e -> e.getAge() > 12).collect(Collectors.toSet());
Note: it is not recommended to use when the data volume is small. It can be used when the data volume is large.