Stream is a new feature in Java8 that allows you to process data declaratively, like SQL statements, filtering, sorting, and aggregating data without making changes to the source data.

The Stream API can simplify our code and greatly improve readability. Let’s look at a few ways to get a feel for it.

Stream.forEach()

You can probably guess from the name of the method, it’s a convection traversal. Void forEach(Consumer
Action), which performs the action specified by the action on each element in the container.

public static void main(String[] args) {

    List<User> userList = getUserList();

    // userId=1

    // userId=2

    // userId=3

    userList.forEach(e -> System.out.println("userId=" + e.getUserId()));

}



private static List<User> getUserList(a) {

    return Arrays.asList(new User().setUserId(1), 

             new User().setUserId(2), 

             new User().setUserId(3));

}

Copy the code

Stream.map()

It can be interpreted as aThe transition function, transforms each element according to some operation.

For example, we need to convert a List to a List and return it to the front end:

Java8 before

List<User> userList = getUserList();



List<UserVO> userVOList = new ArrayList<>();

for (User user : userList) {

    UserVO userVO = new UserVO();

    userVO.setUserId(user.getUserId());

    // omit the set method

    userVOList.add(userVO);

}

Copy the code

Using Java8 Stream

List<User> userList = getUserList();



List<UserVO> userVOList = userList.stream().map(user -> {

    UserVO userVO = new UserVO();

    userVO.setUserId(user.getUserId());

    // omit the set method

    return userVO;

}).collect(Collectors.toList());

Copy the code
  • .stream()Convert a collection to a Stream
  • .collect()For the collection of results
  • Collectors replace flows with collections and aggregation elements

The difference from before Java8 is that the new ArrayList<>() procedure is omitted and the map function is used to map User to UserVO.

Stream.filter()

The function is signed as Stream

filter(Predicate
predicate), which returns a Stream containing only the elements of the predicate condition. In other words, filter is a “filter function.”

Here’s an explanationpredicate, its Chinese meaning is predicate, is a Boolean valued function, can be understood as a condition.For example, we need to get the collection whose userId is odd:

List<User> userList = getUserList();

userList.stream()

    .filter(user -> user.getUserId() % 2= =1)

    .forEach(user -> System.out.println("userId=" + user.getUserId()));



// Console output

// userId=1

// userId=3

Copy the code

Stream.sorted()

It has two method signatures: Stream sorted() and Stream sorted(Comparator<? Super T> comparator), where the former requires elements in the stream to implement the Comparable interface, otherwise thrownClassCastExceptionThe exception.For example, sort the collection in reverse order by userId:

private static List<User> getUserList(a) {

    return Arrays.asList(new User().setUserId(1), 

             new User().setUserId(3), 

             new User().setUserId(2));

}



public static void main(String[] args) {

    // User does not implement the Comparable interface

    List<User> userList = getUserList();

    userList.stream()

        // Exception in thread "main" java.lang.ClassCastException:

        // User cannot be cast to java.lang.Comparable

        .sorted()

        .forEach(user -> System.out.println("userId=" + user.getUserId()));

}



public static void main(String[] args) {

    List<User> userList = getUserList();

    userList.stream()

        .sorted((u1, u2) -> u2.getUserId() - u1.getUserId())

        .forEach(user -> System.out.println("userId=" + user.getUserId()));

}



// Console output

// userId=3

// userId=2

// userId=1



Copy the code

summary

A careful student might notice that forEach() returns no value, while map(), filter(), sorted() return a Stream. In fact, Stream operations fall into two categories:

  • Intermediate operations: always execute lazily;
  • Terminal Operations: The actual calculation is triggered.

In other words, any operation that returns Stream is an intermediate operation. So what is lazy execution? That is, intermediate operations are not executed immediately until the end operation is encountered. For example, the following code will not execute:

Stream.of("a"."b"."c"."d"."e")

    .filter(s -> {

        System.out.println("filter: " + s);

        return true;

    }); 

Copy the code

In this way, we can filter, sort, transform, and collect data through “multiple intermediate actions + 1 end action”.

Finally, a question to ponder: What is the order of multiple intermediate operations? Leave a comment about what you think.