Stream: intermediate operation, termination behavior

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));
    }
}

Keywords: Java stream

Added by rdimaggio on Fri, 04 Mar 2022 15:53:14 +0200