Make Java8 Stream easier

Make Java8 Stream easier

I believe that many little partners of programmers who have just entered the pit are very headache by some code, which makes us feel both familiar and unfamiliar. Many of our new friends are more used to using for loops or iterators to solve some traversal problems, but many old people in the company like to use Stream flow, a new feature of Java 8, so that the requirements can be realized in shorter code, but it is less readable for unfamiliar novices.

1. Why do experienced veterans prefer to use Stream

  • Performance advantages, (large amount of data) faster than iterators
  • Support serial and parallel processing, and parallel processing can make full use of CPU resources
  • A Stream is a Stream that calculates data and does not store data itself
  • Support functional programming
  • Elegant code makes the code more efficient, clean and concise

2. Usage of stream

Three steps:

  • Create Stream
  • Intermediate operation
  • Terminate operation

3. Creation of stream

The creation of a Stream depends on the data source, usually a container or array

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CreateStreamDemo {

    public static void main(String[] args) {
        // 1 creating a Stream through a collection is also the most used form
        List<String> strList = new ArrayList<>();
        // Create serial operation flow
        Stream<String> stream =;
        // Create parallel operation flow
        Stream<String> parallelStream = strList.parallelStream();
        // 2 create a Stream from an array
        int[] arr = new int[]{1,2,3};
        IntStream intStream =;
        // 3 through Stream.of
        Stream<Integer> integerStream = Stream.of(1,2,3);
        Stream<String> stringStream = Stream.of("a","b","c");
        // 4 infinite flow
        // Take one every five numbers
        Stream.iterate(0, t -> t + 5).forEach(System.out::println); // iteration
        Stream.generate(Math::random).forEach(System.out::println); // generate

4. Stream intermediate operation

import com.zhj.java8.bean.Student;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

import static;
import static;

public class MiddleStreamDemo {

    public static void main(String[] args) {

        List<Student> students = new ArrayList<>();
        students.add(new Student(1,"Xiaohua",23,1));
        students.add(new Student(1,"Xiaohua",23,2));
        students.add(new Student(2,"millet",20,2));
        students.add(new Student(3,"Small fruit",30,3));
        students.add(new Student(4,"Xiao Wei",18,2));

        // filter -> stu.getAge() > 20).forEach(System.out::println);

        // duplicate removal
        // The object de duplication is based on the reference, and the repeated content will not be de duplicated unless the equals and hashCode methods are overridden
        System.out.println("----------duplicate removal----------");
        System.out.println("Weight removal 1----------");;
        // For the de duplication of some attributes of objects in the collection, the equals and hashCode methods are not rewritten, but can only be assisted by other data structures
        // A single attribute can be stu - > stu. Getid()
        // Multiple attributes can be stu - > stu. Getid() + ";" + stu. Getname()
        System.out.println("Weight removal 2----------");
        ArrayList<Student> distinctList =
                collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(stu -> stu.getId() + ";" + stu.getName()))), ArrayList::new)

        // Sorting supports defining sorting methods
        // sorted uses natural ordering by default, and its elements must implement the Comparable interface
        System.out.println("Sort 1----------");;
        // Sorted (Comparator <? Super T > Comparator): we can use lambada to create a Comparator instance. You can sort elements in ascending or descending order.
        System.out.println("Sort 2----------");
                .sorted(Comparator.comparing(Student::getAge,Comparator.reverseOrder())) // , Comparator.reverseOrder()
        // Create a comparator and sort multiple attributes through the definition of comparator content, which is similar to the continuous orderBy in sql
        System.out.println("Sort 3----------");
                (s1,s2) -> {
                    if (s1.getAge() == s2.getAge()) {
                        return s1.getSex().compareTo(s2.getSex());
                    } else {
                        return -s1.getAge().compareTo(s2.getAge());
        System.out.println("Sort 4----------");
        Comparator<Student> studentComparator = (s1,s2) -> {
            Integer age1 = s1.getAge();
            Integer age2 = s2.getAge();
            if (age1 != age2) return age1 - age2;
            Integer sex1 = s1.getSex();
            Integer sex2 = s2.getSex();
            if (sex1 != sex2) return sex2 - sex1;
            return 0;

        // Intercept the first three elements

        // Skip the first 3 elements

        // mapping
        System.out.println("mapping Map----------");
        // map receives Lambda, converts elements into other forms, or extracts information and maps it into a new element
        Stream<Stream<Student>> streamStream1 = -> filterStudent(str));
        streamStream1.forEach(sm -> sm.forEach(System.out::println));
        System.out.println("mapping flatMap----------");
        // Map receives Lambda, converts each element in the stream into another stream, and then connects all streams into a stream flattening map
        Stream<Student> studentStream2 = -> filterStudent(str));
        // consumption
        System.out.println("----------consumption----------"); -> stu.setAge(100)).forEach(System.out::println);

    public static Stream<Student> filterStudent(Student student) {
        student = new Student();
        return Stream.of(student);


public class Student implements Comparable<Student> {

    private Integer id;
    private String name;
    private Integer age;
    private Integer sex;

    public Student() {

    public Student(Integer id, String name, Integer age, Integer sex) { = id; = name;
        this.age = age; = sex;

    public Integer getId() {
        return id;

    public void setId(Integer id) { = id;

    public String getName() {
        return name;

    public void setName(String name) { = name;

    public Integer getAge() {
        return age;

    public void setAge(Integer age) {
        this.age = age;

    public Integer getSex() {
        return sex;

    public void setSex(Integer sex) { = sex;

    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", sex=" + sex +

    public int compareTo(Student o) {
        return this.getAge() - o.getAge();

5. Stream termination


import com.zhj.java8.bean.Student;

import java.util.*;

public class TerminationStreamDemo {

    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(1,"Xiaohua",23,1));
        students.add(new Student(2,"millet",20,2));
        students.add(new Student(3,"Small fruit",30,3));
        students.add(new Student(4,"Xiao Wei",18,2));
        students.add(new Student(5,"Xiaohua",23,2));
        System.out.println("--------------------Match aggregation operation--------------------");
        // allMatch: receives a Predicate function. It returns true only when each element in the stream conforms to the assertion. Otherwise, it returns false
        boolean allMatch = -> stu.getAge() > 10);
        System.out.println("All meet the conditions of over 10 years old:" + allMatch);
        // noneMatch: receives a Predicate function. It returns true only when every element in the stream does not conform to the assertion. Otherwise, it returns false
        boolean noneMatch = -> stu.getAge() > 10);
        System.out.println("All of them do not meet the conditions of being over 10 years old:" + noneMatch);
        // anyMatch: receives a Predicate function. As long as an element in the stream satisfies the assertion, it returns true; otherwise, it returns false
        boolean anyMatch = -> stu.getAge() > 20);
        System.out.println("Contains any of the following:" + anyMatch);

        // findFirst: returns the first element in the stream
        Student findFirst =;
        System.out.println("First student:" + findFirst);
        // findAny: returns any element in the stream
        Student findAny =;
        System.out.println("Any student:" + findAny);

        //  count: returns the total number of elements in the stream
        long count =;
        System.out.println("Total number of students:" + count);
        // max: returns the maximum value of the element in the stream
        Student max =;
        System.out.println("Oldest student:" + max);
        // max: returns the maximum value of the element in the stream
        Student min =;
        System.out.println("Youngest student:" + min);

        System.out.println("--------------------Protocol operation--------------------");
        System.out.println("Total student age:" +;
        System.out.println("Maximum student age:" +;

        System.out.println("--------------------Collection operation--------------------");
        List<Student> list =;
        Set<Student> set =;
        Map<Integer, String> map =, Student::getName));
        String joinName =",", "(", ")"));
        // total;
        // Maximum age;
        // Age and;
        // average age;
        // Information collection
        DoubleSummaryStatistics statistics =;
        System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
        // grouping
        Map<Integer, List<Student>> collect =;
        //Multiple grouping, first according to gender and then according to age
        Map<Integer, Map<Integer, List<Student>>> typeAgeMap =, Collectors.groupingBy(Student::getAge)));
        //It is divided into two parts, one is older than 20 years old and the other is less than or equal to 20 years old
        Map<Boolean, List<Student>> partMap = -> v.getAge() > 20));
        Integer allAge =;

6. Stream characteristics

  • Inert execution of intermediate operation

    If there are multiple intermediate operations, there will be no multiple cycles. Multiple conversion operations will only be merged when the operation is terminated, and the cycle will be completed at one time.

  • Internal iteration

  • The iteration after finding the qualified data will not proceed

  • The end of the stream is operated only once

    Exception: stream has already been operated upon or closed

    This means that the flow has been closed, because when we use the end operation, the flow is closed and cannot be called again. If we want to call again, we can only reopen a new flow.

Tags: Java Back-end

Posted on Fri, 29 Oct 2021 02:51:37 -0400 by cmancone