9 pictures and 32 cases take you to play Java stream easily

Posted by petebolduc on Mon, 31 Jan 2022 04:09:53 +0100

Hello, I'm brother Jun.

Java 8 adds Stream processing, which can be used in conjunction with Lambda expressions, making it very convenient to operate collections. Although we often use Stream at ordinary times, we actually use very few methods. This article will fully introduce the use of Stream.

Stream provides many methods. It can be divided into intermediate operation and end operation according to whether the current method is called to end the flow processing.

Intermediate operations can be divided into stateful operations and stateless operations:

  • Stateless operation means that the operation of the current element is not affected by the previous element.

  • Stateful operation means that the operation of the current element can only be carried out after all elements are processed.

The end operation can be divided into short-circuit operation and non short-circuit operation, as follows:

  • Short circuit operation means that it can be completed without processing all elements.

  • Non short circuit operation means that all elements must be processed before it can end.

1 create a Stream

1.1 creating with collections

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
Stream stream = list.stream();

1.2 creating with arrays

String[] array={"ab", "abc", "abcd", "abcde", "abcdef" };
Stream<String> stream = Arrays.stream(array);

1.3 using Stream static method

Stream<String> stream = Stream.of("ab", "abc", "abcd", "abcde", "abcdef");

Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(5);
stream2.forEach(r -> System.out.print(r + " "));

System.out.println();

Stream<Integer> stream3 = Stream.generate(new Random()::nextInt).limit(3);
stream3.forEach(r -> System.out.print(r + " "));

The above code output is as follows:

0 3 6 9 12 

-150231306 -1769565695 102740625

2 stateless operation

2.1 map

Receive a function as an input parameter, apply this function to each element, and the execution result forms a new stream return.

Case 1: add 3 to each element of integer array:

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
List<Integer> newList = list.stream().map(x -> x + 3).collect(Collectors.toList());
System.out.println("newList:" + newList);

The output result of the above code is as follows:

newList:[8, 5, 6, 4, 7]

Case 2: convert each element of the string array to uppercase:

List<String> list = Arrays.asList("ab", "abc", "abcd", "abcde", "abcdef");
List<String> newList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println("newList:" + newList);

The output result of the above code is as follows:

newList:[AB, ABC, ABCD, ABCDE, ABCDEF]

2.2 mapToXXX

It includes three methods: mapToInt, mapToDouble and mapToLong

Case 3: convert string array to integer array:

List<String> list = Arrays.asList("ab", "abc", "abcd", "abcde", "abcdef");
int[] newList = list.stream().mapToInt(r -> r.length()).toArray();
System.out.println("newList:" + Arrays.toString(newList));

The output result of the above code is as follows:

newList:[2, 3, 4, 5, 6]

2.3 flatMap

flatMap receives functions as input parameters, then converts each element in the set into a stream, and then forms these streams into a new stream. It is a good tool for splitting words. As shown below:

Case 4: converting a string array to another string array:

List<String> list = Arrays.asList("ab-abc-abcd-abcde-abcdef", "5-2-3-1-4");
List<String> newList = list.stream().flatMap(s -> Arrays.stream(s.split("-"))).collect(Collectors.toList());
System.out.println("newList: " + newList);

Output result of the above code:

newList: [ab, abc, abcd, abcde, abcdef, 5, 2, 3, 1, 4]

2.4 flatMapToXXX

Similar to flatMap, it returns an XXXStream.

It includes three methods: flatMapToInt, flatMapToLong and flatMapToDouble

Case 5: sum a given two-dimensional integer array:

int[][] data = {{1,2},{3,4},{5,6}};
IntStream intStream = Arrays.stream(data).flatMapToInt(row -> Arrays.stream(row));
System.out.println(intStream.sum());

The output result is: 21.

2.5 filter

The filtering function extracts the qualified elements into a new stream according to certain rules.

Define a student class, which contains four attributes: name, age, gender and test score:

class Student{
    private String name;
    private Integer age;
    private String sex;
    private Integer score;

    public Student(String name, Integer age, String sex, Integer score){
        this.name = name;
        this.age = age;
        this.score = score;
        this.sex = sex;
    }
    //Omit getters/setters
}

Case 6: find out the names of students whose test scores are above 90 points:

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));

List<String> nameList = students.stream().filter(x -> x.getScore() >= 90).map(Student::getName).collect(Collectors.toList());
System.out.print("Name of students with more than 90 scores:" + nameList);

The output is as follows:

Student's name above, Jack, Lucy: [90]

2.6 peek

Returns a new stream composed of elements in the stream, and acts on each element of the new stream with the given function. The incoming function is of type Consume and has no return value, so it will not change the value of the element in the original stream. peek is mainly used for debug ging, which can easily check whether the stream processing results are correct.

Case 7: filter out the string with length greater than 3 in the stream and convert it to uppercase:

Stream.of("one", "two", "three", "four")
             .filter(e -> e.length() > 3)
             .peek(e -> System.out.println("Filtered value: " + e))
             .map(String::toUpperCase)
             .peek(e -> System.out.println("Mapped value: " + e))
             .collect(Collectors.toList());

The output results are as follows:

Filtered value: three 

Mapped value: THREE 

Filtered value: four 

Mapped value: FOUR

2.7 unordered

Turn an ordered stream into an unordered stream. If the original stream itself is unordered, it may return to the original stream.

Case 8: turn an ordered array into an unordered array

Arrays.asList("1", "2", "3", "4", "5")
                .parallelStream()
                .unordered()
                .forEach(r -> System.out.print(r + " "));

The output results of each execution are different. The following are the results of one output:

3 5 4 2 1

3 stateful operation

3.1 distinct

De duplication function.

Case 9: remove duplicate strings from string array

String[] array = { "a", "b", "b", "c", "c", "d", "d", "e", "e"};
List<String> newList = Arrays.stream(array).distinct().collect(Collectors.toList());
System.out.println("newList:" + newList);

Output result:

newList:[a, b, c, d, e]

3.2 limit

Restrict the first n elements from the stream.

Case 10: get the first five elements from the array

String[] array = { "c", "c", "a", "b", "b", "e", "e", "d", "d"};
List<String> newList = Arrays.stream(array).limit(5).collect(Collectors.toList());
System.out.println("newList:" + newList);

Output result:

newList:[c, c, a, b, b]

3.3 skip

Skip the first n elements in the Stream

Case 11: get the element after the fifth element from the array

String[] array = { "a", "b", "c", "d", "e", "f", "g", "h", "i"};
List<String> newList = Arrays.stream(array).skip(5).collect(Collectors.toList());
System.out.println("newList:" + newList);

Output result:

newList:[f, g, h, i]

3.4 sorted

Sorting function.

Case 12: sorting a given array

String[] array = { "c", "c", "a", "b", "b", "e", "e", "d", "d"};
List<String> newList = Arrays.stream(array).sorted().collect(Collectors.toList());
System.out.println("newList:" + newList);

Output result:

newList:[a, b, b, c, c, d, d, e, e]

Case 13: ranking according to students' grades

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));

List<String> nameList = students.stream().sorted(Comparator.comparing(Student::getScore)).map(Student::getName).collect(Collectors.toList());
System.out.print("Output student names by grade:" + nameList);

Output result:

Names of students with more than 90 scores: [Alis, Jessie, Mike, Jack, Allon, Lucy]

4 short circuit operation

4.1 findAny

Find any element in the stream that meets the filtering conditions.

Case 14: find out any student whose score is higher than 90

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));

Optional<Student> studentFindAny = students.stream().filter(x -> x.getScore() > 90).findAny();
System.out.print("Find out the name of any student whose test score is above 90:" + studentFindAny.orElseGet(null).getName());

Output result:

Find out the name of any student whose test score is more than 90: Lucy

4.2 anyMatch

Whether there is any element that meets the given condition.

Case 15: whether there are students with scores higher than 90 and students with scores lower than 50. Still use the student set in case 14 above.

boolean result1 = students.stream().anyMatch(x -> x.getScore() > 90);
System.out.println("Is there a score higher than 90 Students:" + result1);
boolean result2 = students.stream().anyMatch(x -> x.getScore() < 50);
System.out.print("Is there a score below 50 Students:" + result2);

Output result:

Whether there are students with scores higher than 90: true

Whether there are students with scores lower than 50: false

4.3 allMatch

Whether all elements in the collection meet the given conditions. If the collection is empty, it returns true.

Case 16: whether students' scores are higher than 90 and 50. Still use the student set in case 14 above.

boolean result1 = students.stream().allMatch(x -> x.getScore() > 90);
System.out.println("Are all students above 90:" + result1);
boolean result2 = students.stream().allMatch(x -> x.getScore() > 50);
System.out.print("Are all students above 50:" + result2);

Output result:

Are all students above 90: false

Whether all students score above 50: true

4.4 noneMatch

Whether no element can match the given condition. If the collection is empty, return true.

Case 17: is there no student with a score of more than 90 and no student with a score of less than 50. Still use the student set in case 14 above.

boolean result1 = students.stream().noneMatch(x -> x.getScore() > 90);
System.out.println("Is there no student with a grade of 90 Score above:" + result1);
boolean result2 = students.stream().noneMatch(x -> x.getScore() < 50);
System.out.print("Is there no student with a grade of 50 It is divided into the following:" + result2);

Output result:

Is there no student whose score is above 90: false

Is there no student whose score is below 50: true

4.5 findFirst

Find the first eligible element.

Case 18: find out the first student with a score of more than 90. Still use the student set in case 14 above.

Optional<Student> studentFindAny = students.stream().filter(x -> x.getScore() > 90).findFirst();
System.out.print("The first score is 90 Names of students with scores above:" + studentFindAny.orElseGet(null).getName());

Output result:

Name of the first student with a score of more than 90: Lucy

5 non short circuit operation

5.1 forEach

Traverse elements.

Case 19: traversing an array and printing

List<Integer> array = Arrays.asList(5, 2, 3, 1, 4);
array.stream().forEach(System.out :: println);

Output result:

5 2 3 1 4

5.2 forEachOrdered

Output in the order of the elements in a given set. The main usage scenario is to output elements in a given order in the case of parallel flow.

Case 20: traverse an array with a parallel stream and output the results in the order of the given array

List<Integer> array = Arrays.asList(5, 2, 3, 1, 4);
array.parallelStream().forEachOrdered(System.out :: println);

Output result:

5 2 3 1 4

5.3 toArray

Returns an array that includes all elements in a given stream.

Case 21: convert a given character stream into an array

Stream<String> stream = Arrays.asList("ab", "abc", "abcd", "abcde", "abcdef").stream();
String[] newArray1 = stream.toArray(str -> new String[5]);
String[] newArray2 = stream.toArray(String[]::new);
Object[] newArray3 = stream.toArray();

5.4 reduce

The specification operation combines all elements of a stream into one element, such as summation, product, maximum and minimum, etc.

Case 22: find the sum, product and maximum value of integer array elements

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);
Optional<Integer> product = list.stream().reduce((x, y) -> x * y);
Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
System.out.println("Sum of array elements:" + sum.get());
System.out.println("Array element product:" + product.get());
System.out.println("Maximum value of array element:" + max.get());

Output result:

Sum of array elements: 15

Array element product: 120

Maximum value of array element: 5

Case 23: seek the highest score of the whole class and the total score of the whole class

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));
Optional<Integer> maxScore = students.stream().map(r -> r.getScore()).reduce(Integer::max);
Optional<Integer> sumScore = students.stream().map(r -> r.getScore()).reduce(Integer::sum);
System.out.println("The highest score of the whole class:" + maxScore.get());
System.out.println("Total score of the whole class:" + sumScore.get());

Output result:

The highest score of the whole class: 100

Total score of the whole class: 498

5.5 collect

Gather the elements in the stream into a new set or into a single element.

5.5.1 integration into a new set

Methods include toList, toSet, and toMap.

Case 24: according to the student list, the name list, different score list and name score set are summarized. The scores of Mike and Jessie are 88.

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 88));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));
List<String> list = students.stream().map(r -> r.getName()).collect(Collectors.toList());
Set<Integer> set = students.stream().map(r -> r.getScore()).collect(Collectors.toSet());
Map<String, Integer> map = students.stream().collect(Collectors.toMap(Student::getName, Student::getScore));
System.out.println("List of names of students in the class:" + list);
System.out.println("List of different scores of the whole class:" + set);
System.out.println("Student name score set of the whole class:" + map);

Output result:

Name list of students in the class: [Mike, Jack, Lucy, Jessie, Allon, Alis]

List of different scores of the whole class: [50, 100, 88, 90, 92]

Name and score set of the whole class: {Mike=88, Allon=92, Alis=50, Lucy=100, Jack=90, Jessie=88}

5.5.2 statistical function

The statistical function includes the following methods:

Case 25: total, sum, Max / min / average

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
long count = list.stream().collect(Collectors.counting());
int sum = list.stream().collect(Collectors.summingInt(r -> r));
double average = list.stream().collect(Collectors.averagingDouble(r -> r));
Optional<Integer> max = list.stream().collect(Collectors.maxBy(Integer::compare));
Optional<Integer> min = list.stream().collect(Collectors.maxBy((x, y) -> x > y ? y : x));
System.out.println("total:" + count);
System.out.println("the sum:" + sum);
System.out.println("average value:" + average);
System.out.println("Maximum:" + max.get());
System.out.println("minimum value:" + min.get());

Output result:

Total: 5

Total: 15

Average: 3.0

Maximum: 5

Minimum: 5

Case 26: summation statistics

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
IntSummaryStatistics statistics = list.stream().collect(Collectors.summarizingInt(r -> r));
System.out.println("Comprehensive statistical results:" + statistics.toString());

Output result:

Comprehensive statistical results: IntSummaryStatistics{count=5, sum=15, min=1, average=3.000000, max=5}

5.5.3 zoning and grouping

It mainly includes two functions:

  • partitioningBy: divide the stream into two map s

  • Grouping by: divide the stream into multiple map s

Case 27: divide students into zones with scores above 80 and below

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 10,"male", 90));
students.add(new Student("Lucy", 12,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 16,"female", 50));
Map<Boolean, List<Student>> partitionByScore = students.stream().collect(Collectors.partitioningBy(x -> x.getScore() > 80));
System.out.println("Divide students according to their test scores of more than 80 points:");
partitionByScore.forEach((k,v ) -> {
    System.out.print(k ? "80 Score above:" : "80 It is divided into the following:");
    v.forEach(r -> System.out.print(r.getName() + ","));
    System.out.println();
});
System.out.println();

The partition result is to divide the Student list into map s with only true and false key values. The output is as follows:

Divide students according to their test scores of more than 80 points:

Below 80: Jessie,Alis,

Above 80 points: Mike,Jack,Lucy,Allon,

Case 28: students are grouped according to gender and age

Map<String, Map<Integer, List<Student>>> group = students.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge)));
System.out.println("Group students by gender and age:");
group.forEach((k,v ) -> {
    System.out.println(k +": ");
    v.forEach((k1,v1) -> {
        System.out.print("      " + k1 + ":" );
        v1.forEach(r -> System.out.print(r.getName() + ","));
        System.out.println();
    });
});

The output is as follows:

Group students by gender and age:

female:

      16:Allon,Alis, 

      12:Lucy,Jessie, 

male:

      10:Mike,Jack,

5.5.4 connection

Merge the elements in the stream with the specified connector, which can be empty.

Case 29: output the names of all students, separated by commas. Here is the student list in case 27

String studentNames = students.stream().map(r -> r.getName()).collect(Collectors.joining(","));
System.out.println("List of all student names:" + studentNames);

The output is as follows:

List of names of all students: Mike,Jack,Lucy,Jessie,Allon,Alis

5.5.5 regulations

We have talked about the protocol in section 5.4. The protocol here supports more powerful custom protocols.

Case 30: sum each element in the array after adding 1

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
int listSum = list.stream().collect(Collectors.reducing(0, x -> x + 1, (sum, b) -> sum + b));
System.out.println("Sum of each element in the array after adding 1:" + listSum);

Output result:

The sum of each element in the array plus 1: 20

5.6 max,min,count

stream provides a convenient statistical method.

Case 31: count the number of elements with maximum value, minimum value and greater than 3 in the integer array

Hello, I'm brother Jun.

Java 8 adds Stream processing, which can be used in conjunction with Lambda expressions, making it very convenient to operate collections. Although we often use Stream at ordinary times, we actually use very few methods. This article will fully introduce the use of Stream.

Stream provides many methods. It can be divided into intermediate operation and end operation according to whether the current method is called to end the flow processing.

Intermediate operations can be divided into stateful operations and stateless operations:

  • Stateless operation means that the operation of the current element is not affected by the previous element.

  • Stateful operation means that the operation of the current element can only be carried out after all elements are processed.

The end operation can be divided into short-circuit operation and non short-circuit operation, as follows:

  • Short circuit operation means that it can be completed without processing all elements.

  • Non short circuit operation means that all elements must be processed before it can end.

1 create a Stream

1.1 creating with collections

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
Stream stream = list.stream();

1.2 creating with arrays

String[] array={"ab", "abc", "abcd", "abcde", "abcdef" };
Stream<String> stream = Arrays.stream(array);

1.3 using Stream static method

Stream<String> stream = Stream.of("ab", "abc", "abcd", "abcde", "abcdef");

Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(5);
stream2.forEach(r -> System.out.print(r + " "));

System.out.println();

Stream<Integer> stream3 = Stream.generate(new Random()::nextInt).limit(3);
stream3.forEach(r -> System.out.print(r + " "));

The above code output is as follows:

0 3 6 9 12 

-150231306 -1769565695 102740625

2 stateless operation

2.1 map

Receive a function as an input parameter, apply this function to each element, and the execution result forms a new stream return.

Case 1: add 3 to each element of integer array:

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
List<Integer> newList = list.stream().map(x -> x + 3).collect(Collectors.toList());
System.out.println("newList:" + newList);

The output result of the above code is as follows:

newList:[8, 5, 6, 4, 7]

Case 2: convert each element of the string array to uppercase:

List<String> list = Arrays.asList("ab", "abc", "abcd", "abcde", "abcdef");
List<String> newList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println("newList:" + newList);

The output result of the above code is as follows:

newList:[AB, ABC, ABCD, ABCDE, ABCDEF]

2.2 mapToXXX

It includes three methods: mapToInt, mapToDouble and mapToLong

Case 3: convert string array to integer array:

List<String> list = Arrays.asList("ab", "abc", "abcd", "abcde", "abcdef");
int[] newList = list.stream().mapToInt(r -> r.length()).toArray();
System.out.println("newList:" + Arrays.toString(newList));

The output result of the above code is as follows:

newList:[2, 3, 4, 5, 6]

2.3 flatMap

flatMap receives functions as input parameters, then converts each element in the set into a stream, and then forms these streams into a new stream. It is a good tool for splitting words. As shown below:

Case 4: converting a string array to another string array:

List<String> list = Arrays.asList("ab-abc-abcd-abcde-abcdef", "5-2-3-1-4");
List<String> newList = list.stream().flatMap(s -> Arrays.stream(s.split("-"))).collect(Collectors.toList());
System.out.println("newList: " + newList);

Output result of the above code:

newList: [ab, abc, abcd, abcde, abcdef, 5, 2, 3, 1, 4]

2.4 flatMapToXXX

Similar to flatMap, it returns an XXXStream.

It includes three methods: flatMapToInt, flatMapToLong and flatMapToDouble

Case 5: sum a given two-dimensional integer array:

int[][] data = {{1,2},{3,4},{5,6}};
IntStream intStream = Arrays.stream(data).flatMapToInt(row -> Arrays.stream(row));
System.out.println(intStream.sum());

The output result is: 21.

2.5 filter

The filtering function extracts the qualified elements into a new stream according to certain rules.

Define a student class, which contains four attributes: name, age, gender and test score:

class Student{
    private String name;
    private Integer age;
    private String sex;
    private Integer score;

    public Student(String name, Integer age, String sex, Integer score){
        this.name = name;
        this.age = age;
        this.score = score;
        this.sex = sex;
    }
    //Omit getters/setters
}

Case 6: find out the names of students whose test scores are above 90 points:

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));

List<String> nameList = students.stream().filter(x -> x.getScore() >= 90).map(Student::getName).collect(Collectors.toList());
System.out.print("Name of students with more than 90 scores:" + nameList);

The output is as follows:

Student's name above, Jack, Lucy: [90]

2.6 peek

Returns a new stream composed of elements in the stream, and acts on each element of the new stream with the given function. The incoming function is of type Consume and has no return value, so it will not change the value of the element in the original stream. peek is mainly used for debug ging, which can easily check whether the stream processing results are correct.

Case 7: filter out the string with length greater than 3 in the stream and convert it to uppercase:

Stream.of("one", "two", "three", "four")
             .filter(e -> e.length() > 3)
             .peek(e -> System.out.println("Filtered value: " + e))
             .map(String::toUpperCase)
             .peek(e -> System.out.println("Mapped value: " + e))
             .collect(Collectors.toList());

The output results are as follows:

Filtered value: three 

Mapped value: THREE 

Filtered value: four 

Mapped value: FOUR

2.7 unordered

Turn an ordered stream into an unordered stream. If the original stream itself is unordered, it may return to the original stream.

Case 8: turn an ordered array into an unordered array

Arrays.asList("1", "2", "3", "4", "5")
                .parallelStream()
                .unordered()
                .forEach(r -> System.out.print(r + " "));

The output results of each execution are different. The following are the results of one output:

3 5 4 2 1

3 stateful operation

3.1 distinct

De duplication function.

Case 9: remove duplicate strings from string array

String[] array = { "a", "b", "b", "c", "c", "d", "d", "e", "e"};
List<String> newList = Arrays.stream(array).distinct().collect(Collectors.toList());
System.out.println("newList:" + newList);

Output result:

newList:[a, b, c, d, e]

3.2 limit

Restrict the first n elements from the stream.

Case 10: get the first five elements from the array

String[] array = { "c", "c", "a", "b", "b", "e", "e", "d", "d"};
List<String> newList = Arrays.stream(array).limit(5).collect(Collectors.toList());
System.out.println("newList:" + newList);

Output result:

newList:[c, c, a, b, b]

3.3 skip

Skip the first n elements in the Stream

Case 11: get the element after the fifth element from the array

String[] array = { "a", "b", "c", "d", "e", "f", "g", "h", "i"};
List<String> newList = Arrays.stream(array).skip(5).collect(Collectors.toList());
System.out.println("newList:" + newList);

Output result:

newList:[f, g, h, i]

3.4 sorted

Sorting function.

Case 12: sorting a given array

String[] array = { "c", "c", "a", "b", "b", "e", "e", "d", "d"};
List<String> newList = Arrays.stream(array).sorted().collect(Collectors.toList());
System.out.println("newList:" + newList);

Output result:

newList:[a, b, b, c, c, d, d, e, e]

Case 13: ranking according to students' grades

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));

List<String> nameList = students.stream().sorted(Comparator.comparing(Student::getScore)).map(Student::getName).collect(Collectors.toList());
System.out.print("Output student names by grade:" + nameList);

Output result:

Names of students with more than 90 scores: [Alis, Jessie, Mike, Jack, Allon, Lucy]

4 short circuit operation

4.1 findAny

Find any element in the stream that meets the filtering conditions.

Case 14: find out any student whose score is higher than 90

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));

Optional<Student> studentFindAny = students.stream().filter(x -> x.getScore() > 90).findAny();
System.out.print("Find out the name of any student whose test score is above 90:" + studentFindAny.orElseGet(null).getName());

Output result:

Find out the name of any student whose test score is more than 90: Lucy

4.2 anyMatch

Whether there is any element that meets the given condition.

Case 15: whether there are students with scores higher than 90 and students with scores lower than 50. Still use the student set in case 14 above.

boolean result1 = students.stream().anyMatch(x -> x.getScore() > 90);
System.out.println("Is there a score higher than 90 Students:" + result1);
boolean result2 = students.stream().anyMatch(x -> x.getScore() < 50);
System.out.print("Is there a score below 50 Students:" + result2);

Output result:

Whether there are students with scores higher than 90: true

Whether there are students with scores lower than 50: false

4.3 allMatch

Whether all elements in the collection meet the given conditions. If the collection is empty, it returns true.

Case 16: whether students' scores are higher than 90 and 50. Still use the student set in case 14 above.

boolean result1 = students.stream().allMatch(x -> x.getScore() > 90);
System.out.println("Are all students above 90:" + result1);
boolean result2 = students.stream().allMatch(x -> x.getScore() > 50);
System.out.print("Are all students above 50:" + result2);

Output result:

Are all students above 90: false

Whether all students score above 50: true

4.4 noneMatch

Whether no element can match the given condition. If the collection is empty, return true.

Case 17: is there no student with a score of more than 90 and no student with a score of less than 50. Still use the student set in case 14 above.

boolean result1 = students.stream().noneMatch(x -> x.getScore() > 90);
System.out.println("Is there no student with a grade of 90 Score above:" + result1);
boolean result2 = students.stream().noneMatch(x -> x.getScore() < 50);
System.out.print("Is there no student with a grade of 50 It is divided into the following:" + result2);

Output result:

Is there no student whose score is above 90: false

Is there no student whose score is below 50: true

4.5 findFirst

Find the first eligible element.

Case 18: find out the first student with a score of more than 90. Still use the student set in case 14 above.

Optional<Student> studentFindAny = students.stream().filter(x -> x.getScore() > 90).findFirst();
System.out.print("The first score is 90 Names of students with scores above:" + studentFindAny.orElseGet(null).getName());

Output result:

Name of the first student with a score of more than 90: Lucy

5 non short circuit operation

5.1 forEach

Traverse elements.

Case 19: traversing an array and printing

List<Integer> array = Arrays.asList(5, 2, 3, 1, 4);
array.stream().forEach(System.out :: println);

Output result:

5 2 3 1 4

5.2 forEachOrdered

Output in the order of the elements in a given set. The main usage scenario is to output elements in a given order in the case of parallel flow.

Case 20: traverse an array with a parallel stream and output the results in the order of the given array

List<Integer> array = Arrays.asList(5, 2, 3, 1, 4);
array.parallelStream().forEachOrdered(System.out :: println);

Output result:

5 2 3 1 4

5.3 toArray

Returns an array that includes all elements in a given stream.

Case 21: convert a given character stream into an array

Stream<String> stream = Arrays.asList("ab", "abc", "abcd", "abcde", "abcdef").stream();
String[] newArray1 = stream.toArray(str -> new String[5]);
String[] newArray2 = stream.toArray(String[]::new);
Object[] newArray3 = stream.toArray();

5.4 reduce

The specification operation combines all elements of a stream into one element, such as summation, product, maximum and minimum, etc.

Case 22: find the sum, product and maximum value of integer array elements

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);
Optional<Integer> product = list.stream().reduce((x, y) -> x * y);
Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
System.out.println("Sum of array elements:" + sum.get());
System.out.println("Array element product:" + product.get());
System.out.println("Maximum value of array element:" + max.get());

Output result:

Sum of array elements: 15

Array element product: 120

Maximum value of array element: 5

Case 23: seek the highest score of the whole class and the total score of the whole class

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));
Optional<Integer> maxScore = students.stream().map(r -> r.getScore()).reduce(Integer::max);
Optional<Integer> sumScore = students.stream().map(r -> r.getScore()).reduce(Integer::sum);
System.out.println("The highest score of the whole class:" + maxScore.get());
System.out.println("Total score of the whole class:" + sumScore.get());

Output result:

The highest score of the whole class: 100

Total score of the whole class: 498

5.5 collect

Gather the elements in the stream into a new set or into a single element.

5.5.1 integration into a new set

Methods include toList, toSet, and toMap.

Case 24: according to the student list, the name list, different score list and name score set are summarized. The scores of Mike and Jessie are 88.

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 13,"male", 90));
students.add(new Student("Lucy", 15,"female", 100));
students.add(new Student("Jessie", 12,"female", 88));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 22,"female", 50));
List<String> list = students.stream().map(r -> r.getName()).collect(Collectors.toList());
Set<Integer> set = students.stream().map(r -> r.getScore()).collect(Collectors.toSet());
Map<String, Integer> map = students.stream().collect(Collectors.toMap(Student::getName, Student::getScore));
System.out.println("List of names of students in the class:" + list);
System.out.println("List of different scores of the whole class:" + set);
System.out.println("Student name score set of the whole class:" + map);

Output result:

Name list of students in the class: [Mike, Jack, Lucy, Jessie, Allon, Alis]

List of different scores of the whole class: [50, 100, 88, 90, 92]

Name and score set of the whole class: {Mike=88, Allon=92, Alis=50, Lucy=100, Jack=90, Jessie=88}

5.5.2 statistical function

The statistical function includes the following methods:

Case 25: total, sum, Max / min / average

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
long count = list.stream().collect(Collectors.counting());
int sum = list.stream().collect(Collectors.summingInt(r -> r));
double average = list.stream().collect(Collectors.averagingDouble(r -> r));
Optional<Integer> max = list.stream().collect(Collectors.maxBy(Integer::compare));
Optional<Integer> min = list.stream().collect(Collectors.maxBy((x, y) -> x > y ? y : x));
System.out.println("total:" + count);
System.out.println("the sum:" + sum);
System.out.println("average value:" + average);
System.out.println("Maximum:" + max.get());
System.out.println("minimum value:" + min.get());

Output result:

Total: 5

Total: 15

Average: 3.0

Maximum: 5

Minimum: 5

Case 26: summation statistics

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
IntSummaryStatistics statistics = list.stream().collect(Collectors.summarizingInt(r -> r));
System.out.println("Comprehensive statistical results:" + statistics.toString());

Output result:

Comprehensive statistical results: IntSummaryStatistics{count=5, sum=15, min=1, average=3.000000, max=5}

5.5.3 zoning and grouping

It mainly includes two functions:

  • partitioningBy: divide the stream into two map s

  • Grouping by: divide the stream into multiple map s

Case 27: divide students into zones with scores above 80 and below

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 10,"male", 90));
students.add(new Student("Lucy", 12,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 16,"female", 50));
Map<Boolean, List<Student>> partitionByScore = students.stream().collect(Collectors.partitioningBy(x -> x.getScore() > 80));
System.out.println("Divide students according to their test scores of more than 80 points:");
partitionByScore.forEach((k,v ) -> {
    System.out.print(k ? "80 Score above:" : "80 It is divided into the following:");
    v.forEach(r -> System.out.print(r.getName() + ","));
    System.out.println();
});
System.out.println();

The partition result is to divide the Student list into map s with only true and false key values. The output is as follows:

Divide students according to their test scores of more than 80 points:

Below 80: Jessie,Alis,

Above 80 points: Mike,Jack,Lucy,Allon,

Case 28: students are grouped according to gender and age

Map<String, Map<Integer, List<Student>>> group = students.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge)));
System.out.println("Group students by gender and age:");
group.forEach((k,v ) -> {
    System.out.println(k +": ");
    v.forEach((k1,v1) -> {
        System.out.print("      " + k1 + ":" );
        v1.forEach(r -> System.out.print(r.getName() + ","));
        System.out.println();
    });
});

The output is as follows:

Group students by gender and age:

female:

      16:Allon,Alis, 

      12:Lucy,Jessie, 

male:

      10:Mike,Jack,

5.5.4 connection

Merge the elements in the stream with the specified connector, which can be empty.

Case 29: output the names of all students, separated by commas. Here is the student list in case 27

String studentNames = students.stream().map(r -> r.getName()).collect(Collectors.joining(","));
System.out.println("List of all student names:" + studentNames);

The output is as follows:

List of names of all students: Mike,Jack,Lucy,Jessie,Allon,Alis

5.5.5 regulations

We have talked about the protocol in section 5.4. The protocol here supports more powerful custom protocols.

Case 30: sum each element in the array after adding 1

List<Integer> list = Arrays.asList(5, 2, 3, 1, 4);
int listSum = list.stream().collect(Collectors.reducing(0, x -> x + 1, (sum, b) -> sum + b));
System.out.println("Sum of each element in the array after adding 1:" + listSum);

Output result:

The sum of each element in the array plus 1: 20

5.6 max,min,count

stream provides a convenient statistical method.

Case 31: count the number of elements with maximum value, minimum value and greater than 3 in the integer array

Output result:

Maximum value of array element: 5

Minimum value of array element: 1

Number of elements greater than 3 in the array: 2

Case 32: name of the student with the highest score

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 10,"male", 90));
students.add(new Student("Lucy", 12,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 16,"female", 50));
Optional<Student> optional = students.stream().max(Comparator.comparing(r -> r.getScore()));
System.out.println("Name of the student with the highest score:" + optional.get().getName());

Output result:

Name of the student with the highest score: Lucy

        ··············  END  ··············

Output result:

Maximum value of array element: 5

Minimum value of array element: 1

Number of elements greater than 3 in the array: 2

Case 32: name of the student with the highest score

List<Student> students = new ArrayList<>();
students.add(new Student("Mike", 10, "male", 88));
students.add(new Student("Jack", 10,"male", 90));
students.add(new Student("Lucy", 12,"female", 100));
students.add(new Student("Jessie", 12,"female", 78));
students.add(new Student("Allon", 16,"female", 92));
students.add(new Student("Alis", 16,"female", 50));
Optional<Student> optional = students.stream().max(Comparator.comparing(r -> r.getScore()));
System.out.println("Name of the student with the highest score:" + optional.get().getName());

Output result:

Name of the student with the highest score: Lucy

Topics: Java stream