Stream stream operation of List

Stream is called "stream" in Chinese. By transforming the set into such a sequence of elements called "stream", it can carry out a series of parallel or serial pipeline operations on each element in the set in a declarative way.

The benefits of functional programming are particularly obvious. This kind of code expresses the intention of business logic more than its implementation mechanism. Readable code is also easier to maintain, more reliable, and less error prone.

In the face of one to many structure, how to write the list of sub entities of the primary entity when querying the primary entity? Find out the main list and cyclic difference sub list

The Stream operation of list can simplify our code, reduce the pressure of program operation and deal with the above problems. In the past, we first find the corresponding list data, and then find the data in the corresponding sub entity according to the id in the set, and then put it into the corresponding set. The key value represents the id of the primary entity, and the value represents the combined data found in the id of the corresponding primary entity. In this way, the data will be assembled in three foreach cycles, It will be very troublesome. When the amount of data is large, it will increase the load of program operation and cause slow operation. Therefore, the Stream operation replaces our batch of operations, which improves the simplicity, maintainability and reliability of the code and is less prone to error.


The Works of Liezi
First, we create a Person generic List

List<Person> list = new ArrayList<>();
list.add(new Person("jack", 20));
list.add(new Person("mike", 25));
list.add(new Person("tom", 30));


The Person class contains two member variables: age and name

private String name;
private int age;


  1. stream() / parallelStream()
    The most commonly used method is to convert a collection into a stream
List list = new ArrayList();
// return Stream<E>

parallelStream() is a parallel stream method that enables data sets to perform parallel operations

  1. filter(T -> boolean)
    Keep the element with boolean as true
//Keep the age of 20 person element
list =
            .filter(person -> person.getAge() == 20)

Printout [Person{name='jack', age=20}]

collect(toList()) can convert a stream to a List type

  1. distinct()
    Remove duplicate elements. This method determines whether two elements are equal through the equals method of the class
    For example, for the Person class in the example, the equals method needs to be defined first. Otherwise, situations like [Person{name='jack', age=20}, Person{name='jack', age=20}] will not be handled
  2. sorted() / sorted((T, T) -> int)
    If the class of the elements in the stream implements the Comparable interface, that is, it has its own sorting rules, you can directly call the sorted() method to sort the elements, such as stream < integer >
    On the contrary, you need to call sorted ((T, t) - > int) to implement the Comparator interface
//Compare by age:
list =
           .sorted((p1, p2) -> p1.getAge() - p2.getAge())

Of course, this can be simplified to

list =
  1. limit(long n)
    Return the first n elements
list =

Printout [Person{name='jack', age=20}, Person{name='mike', age=25}]
  1. skip(long n)
    Remove the first n elements
list =

Printout [Person{name='tom', age=30}]


When used before limit(n), first remove the first m elements and then return the first n elements of the remaining elements
When limit(n) is used in front of skip(m), first return the first n elements, and then remove m elements from the obtained n elements

list =

Printout [Person{name='mike', age=25}]
  1. map(T -> R)
    Map each element T in the stream to R (similar to type conversion)
List<String> newlist =;

The element in the newlist is the name variable of each Person object in the list

  1. flatMap(T -> Stream<R>)
    Map each element T in the flow into a flow, and then connect each flow into a flow
List<String> list = new ArrayList<>();
list.add("aaa bbb ccc");
list.add("ddd eee fff");
list.add("ggg hhh iii");

list = -> s.split(" ")).flatMap(Arrays::stream).collect(toList());

In the above example, our purpose is to separate each string element in the List with "" and turn it into a new List < string >.

First, the map method divides each String element, but at this time, the type of the stream is stream < String [] >, because the split method returns the type of String []; Therefore, we need to use the flatMap method. First, use Arrays::stream to turn each String [] element into a stream < String > stream, then flatMap will connect each stream into a stream, and finally return the stream < String > we need

  9. anyMatch(T -> boolean)

Is there an element in the stream that matches the given t - > Boolean condition
Whether there is a person object whose age is equal to 20:

boolean b = -> person.getAge() == 20);

  10. allMatch(T -> boolean)


Whether all elements in the stream match the given t - > Boolean condition

  11. noneMatch(T -> boolean)
Whether no element in the stream matches the given t - > Boolean condition

  12.findAny() and findFirst()

findAny(): find one of the elements (the first element is found when using stream(); One of the elements was found when paralleling with parallelStream()
findFirst(): find the first element

It is worth noting that these two methods return an optional < T > object, which is a container class that can represent the existence or non existence of a value, which will be discussed later

  1. Reduce ((T, t) - > t) and reduce (T, (T, t) - > t)
    It is used to combine the elements in the flow, such as summation, quadrature, maximum, etc
Calculate the total age:
int sum =, (a, b) -> a + b);
Same as:
int sum =, Integer::sum);

Among them, the first parameter of reduce 0 means that the starting value is 0. Lambda (a, b) - > A + B means that the two values are added to produce a new value


Calculate the total product of age:
int sum =, (a, b) -> a * b);

Of course

Optional<Integer> sum =;


That is, it does not accept any initial value, but because there is no initial value, it needs to consider that the result may not exist, so it returns the Optional type
  1. count()
    Returns the number of elements in the stream, and the result is of type long
  2. collect()
    For collection methods, we often use collect(toList()), and of course, collect(toSet()), etc. the parameter is a collector interface
    Many reduction operations are implemented, such as converting streams into sets and aggregation elements. Collectors can be used to return lists or strings:
    List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
    List<String> filtered = -> !string.isEmpty()).collect(Collectors.toList());
    System.out.println("Filter list: " + filtered);
    String mergedString = -> !string.isEmpty()).collect(Collectors.joining(", "));
    System.out.println("Merge string: " + mergedString);


  3. The returned result is void. Obviously, we can do something with it, for example:
Print each element:;


ean b = -> person.getAge() == 20);


Tags: Java

Posted by kentopolis on Mon, 18 Apr 2022 19:05:32 +0930