Use of Stream streams in Jdk8 to get you out of the for loop

Learning requirements:
A little knowledge of functional interfaces and Lambda expressions is helpful for better learning.

1. Experience the benefits of Stream first

Requirements: Give you an ArrayList to save your students'results and let you print out results greater than 60.

 public static void main(String[] args) {
        ArrayList<Integer> arrList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            arrList.add((int) (Math.random() * 100));
        }

        printValue1(arrList);

    }

Solution 1:
This ArrayList, of course, is traversed, and if it is greater than 60, it will be output with the following code:

 private static void printValue1(ArrayList<Integer> arrList) {
        for (Integer i : arrList) {
            if (i > 60) {
                System.out.printf("%d ",i);
            }
        }
    }

Solution 2:
Using Stream stream operation, only one line of code is required

 /**
     * Use Stream operation
     *
     * @param arrList
     */
    private static void printValue2(ArrayList<Integer> arrList) {
        arrList.stream().filter(i -> i > 60).forEach(System.out::println);
    }

2. What is Stream Stream Stream?

The concept of stream stream stream was introduced in Jdk1.8. This "stream" is different from the input and output streams in IO. It is a class in Jdk, located in: java.util.stream.Stream
There are three main operations on it: get stream, intermediate operation, and final operation

2.1 How do I get streams?

Getting streams means converting other objects (non-Stream objects) into Stream objects.Only two types of objects can be converted to Stream objects:

  • Array (elements in this array must be of reference type)
   Integer[] iArr = {12, 14, 15, 15, 17, 19, 22};
   Stream<Integer> stream1 = Stream.of(iArr);
  • aggregate
List<T> list = new ArrayList<T>();
Stream<T> stream = list.stream();

2.2 Intermediate operation (returning a new Stream object)

When we get this stream object from above, we can do this with the Stream object, which can be executed indefinitely until the end of the operation.You can see the source code for this class in the development tools, which has the following main operations:

If you're careful, you'll see that most of the parameters in this class's methods are all a functional interface (see the previous article), so that's why you can use Lambda expressions

  • map converts one type of value to another and returns a new Stream
// Convert strings in a collection to uppercase
        Stream<String> stream0 = Stream.of("a", "b", "hello")
                .map(new Function<String, String>() {
                    @Override
                    public String apply(String s) {
                        return s.toUpperCase();
                    }
                });
        //The code above can be abbreviated using Lambda expressions in the following format
        Stream<String> stream = Stream.of("a", "b", "hello")
                .map(s -> s.toUpperCase());

So it's important to understand the operation of Lambda expressions

  • A filter traverses the data and examines and filters the elements

//Filter data with a length greater than 1 in the string collection

Stream<String> stream1 = Stream.of("a", "abc", "abcdefg")
                .filter(value -> value.length() > 1);
  • flatMap can replace values with Stream, then join multiple Streams into one Stream, replacing each element that previously generated the Stream stream with a new Stream object.
      Stream<Integer> stream2 = Stream.of(1, 2)
                .flatMap(numbers -> Stream.of(5, 6, 6, 7, 8));

In the Stream that the top code will generate, it will replace 1,2 with 5,6,7,8,5,6,7,8

  • Other common operations are:
    stream.limit(5) //Limit, take only the first few elements
                .skip(1) //To skip means to skip the first few elements
                .distinct() //Duplicate removal
                .sorted() //Natural Sorting
                .sorted(Integer::compareTo)//Custom Sorting

2.3 Final Operations

The end result is to achieve what we want, including printing, changing to other objects (mainly collections, and subclass objects of functional interfaces).It can only be executed once, and no more operations can be performed after execution is closed.

  • reduce is typically used to calculate the accumulation, as shown in the following code
  // Gets the cumulative value, reduce First parameter is the initial value
        Integer count = Stream.of(1, 2, 3)
                .reduce(0, (o1, o2) -> o1 + o2);
        System.out.println(count);//6
  • collect converts a stream to another form.Parameters are some of the static methods passed into Collectors, such as the following:
Set<Integer> collect = stream.collect(Collectors.toSet());
List<Integer> collect2 = stream.collect(Collectors.toList());
HashSet<Integer> collect1 = stream.collect(Collectors.toCollection(HashSet::new));

List<Integer> list = Stream.of(1, 2)
                .collect(Collectors.toList());
  • forEach traverses elements in this stream object
    Stream.of(1, 2).forEach(i -> System.out.print(i));
        System.out.println();
        //Top formats can be simplified using static method references
        Stream.of(1, 2).forEach(System.out::print);

Finally, let's write a simple example to compare the simplicity and performance of using previous traversal and Stream stream operations
Code Address
Removing the maximum and minimum differences, Stream streams operate slightly slower than using iterators, but this is a small difference

Tags: Java Lambda JDK

Posted on Tue, 04 Feb 2020 11:50:02 -0800 by allanric