What's new in Java 8 - Stream API

1, Introduction to Stream

1.1 Stream API description

  • Stream API(java.util.stream) introduces the true functional programming style into Java, providing simple and efficient operation
  • Stream is a key abstract concept for processing collections in Java 8. It can specify operations on collections and perform very complex operations such as finding, filtering and mapping data. Using the Stream API to operate on the collection data is similar to a database query executed using SQL. You can also use the Stream API to perform operations in parallel

1.2 what is a Stream

Stream is a data channel used to manipulate the sequence of elements generated by data sources (sets, arrays, etc.). A collection stores data, and a stream calculates the collection elements

  • Stream does not store elements in this province
  • Stream does not change the source object, but returns a new stream that holds the result
  • Stream is delayed and can only be executed when results are needed

1.3 Stream operation steps

  • Create Stream

    Get a stream from a data source (such as a collection or array)

  • Intermediate operation

    An intermediate operation chain can perform multiple operations to process the data of the data source

  • Terminate operation

    Once the termination operation is executed, the intermediate operation chain is executed and the results are generated. After that, the created flow can no longer be used. If it is used, a new flow needs to be created

2, Stream usage

2.1 create execution flow

  • Create execution flow from collection

    List<User> userList = User.getUserList();
    //Create sequential flow
    Stream<User> userStream = userList.stream();
    //Create parallel streams, and intermediate operations can be performed in parallel
    Stream<User> userParallelStream = userList.parallelStream();

    The default stream and parallelStream methods are implemented in the Collection interface, so the Collection implementation class can call these two methods directly

  • Create execution flow from array

    int[] intArr = {1,2,3,4,5,6};
    IntStream intStream = Arrays.stream(intArr);
    int[] longArr = {1,2,3,4,5,6};
    IntStream longStream = Arrays.stream(longArr);
    double[] doubleArr = {1.1,2.2,3.3};
    DoubleStream stream = Arrays.stream(doubleArr);
    User[] userArr = {new User(1,"zhangsan",25),new User(2,"lisi",26)};
    Stream<User> userStream = Arrays.stream(userArr);

    The Arrays tool class provides a static stream method implementation, in which the Arrays of basic types int, long and double return the execution flow corresponding to the basic type

  • Created by the of method of Stream

    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
    Stream<Boolean> booleanStream = Stream.of(true, false);
    Stream<Float> floatStream = Stream.of(1.1f, 2.2f, 3.3f);

    When creating an execution flow of a basic data type through the of method, the execution flow of the wrapper type corresponding to the returned basic type

  • Create an infinite Stream through Stream's iterate() and generate()

    Stream.iterate(0,t -> t+2).limit(10).forEach(System.out::println);

    Iterate always generates data through iteration. The first parameter is the starting value, and the subsequent lambda expression is the specific iteration logic. If it is not limited by the subsequent limit method, it will iterate all the time

    generate generates data by repeatedly calling lambda expressions. If there is no limit, the lambda expressions inside will be called all the time

2.2 intermediate operation of stream

The intermediate operations of Stream can be connected to form a call chain (pipeline). Only when the pipeline executes the termination operation, the intermediate operation will be executed. Otherwise, the intermediate operation will not be processed, but will be processed at one time when the operation is terminated. This method is called "lazy evaluation"

  • Screening and slicing

    //Filter out users older than 25. The filter parameter is the implementation of the predict function interface
    List<User> userList = User.getUserList();
    userList.stream().filter(user -> user.getAge() >25).forEach(System.out::println);
    //Limit the number of collection elements and output only three users
    List<User> userList = User.getUserList();
    //Skip the set elements of the number of previous instructions. In the example, skip the first two
    List<User> userList = User.getUserList();
    //distinct de duplication: remove duplicate elements through hashCode() and equals() of the elements generated by the stream
    List<User> userListDistinct = new ArrayList<User>(){
            new User(1,"lizhi",23);
            new User(1,"lizhi",23);
            new User(1,"lizhi",23);

    If the Stream has already performed the termination operation, calling the Stream API of the Stream again will cause an exception: java.lang.IllegalStateException: stream has already been operated upon or closed

  • mapping

    //By mapping the elements of the original Stream to the Stream composed of new elements
    List<String> list = Arrays.asList("aa","bb","cc");
    //Map the user entity collection to the user's name collection
    List<User> userList = User.getUserList();
    Stream<String> nameStream = userList.stream().map(User::getName);
    nameStream.filter(name -> name.startsWith("li")).forEach(System.out::println);
    //flatmap takes a function as a parameter, maps each value in a stream to another stream, and then combines all streams into one stream
    Stream<Character> characterStream = list.stream().flatMap(StreamOperateTest::stringFormat);
    /** Original writing */
    Stream<Stream<Character>> streamStream = list.stream().map(StreamOperateTest::stringFormat);
    streamStream.forEach(stream -> stream.forEach(System.out::println));
    public static Stream<Character> stringFormat(String string){
        List<Character> list = new ArrayList<>(8);
        for (Character c: string.toCharArray()) {
        return list.stream();

    Mapping transforms the original Stream stream into a new Stream stream through the mapping relationship

  • sort

    //Default sort
    List<Integer> integerList = Arrays.asList(12, 95, 32, 2, 95, -2, 35);
    //Custom sorting
    List<User> userList = User.getUserList();

2.3 termination

  • Find and match

    //Check that all elements match
    List<User> userList = User.getUserList();
    boolean allMatch = userList.stream().allMatch(user -> user.getAge() > 24);
    //Check to see if any of the elements match
    boolean anyMatch = userList.stream().anyMatch(user -> user.getAge() > 25);
    //Check if there are no matching elements
    boolean noneMatch = userList.stream().noneMatch(user -> user.getAge() > 25);
    //Find first element
    Optional<User> firstUser = userList.stream().findFirst();
    //Find any element
    Optional<User> anyUser = userList.stream().findAny();
    //Count the number of elements in the stream
    long count = userList.stream().count();
    //Maximum value in the statistical flow. If there are multiple maximum ages of users to be compared, any one will be returned
    Optional<User> maxUser = userList.stream().max(Comparator.comparing(User::getAge));
  • reduction

    //Combine the elements in the flow repeatedly to get a value
    //The and the first parameter of the element in the calculation set are the starting values and also participate in the operation
    List<Integer> integerList = Arrays.asList(5, 6, 8, 22, 72, 365, 85);
    Integer reduce = integerList.stream().reduce(0, Integer::sum);
    //The User is transformed into an age stream through map without repeated operation of the initial value
    Optional<Integer> allAge = userList.stream().map(User::getAge).reduce(Integer::sum);
  • collect

    //Collect the data after the operation into a collection
    List<User> userList = User.getUserList();
    List<User> collect = userList.stream().filter(user -> 
                                                  user.getAge() > 25).collect(Collectors.toList());
    Set<User> userSet = userList.stream().filter(user -> 

Keywords: Java

Added by jimdelong on Tue, 21 Sep 2021 09:33:41 +0300