preface

Only a bald head can be strong.

Welcome to our GitHub repository Star: github.com/ZhongFuChen…

Last article explained the use of Lambda expressions “recently learned basic knowledge of Lambda expressions,” have not seen the students can first read ha ~

I believe many students would like to know: which scenarios are Lambda expressions used more in work? Lambda will use Stream more often

The first time you look at the code for a Stream, it’s a bit confusing (it doesn’t look like it’s written in Java). I hope this article will open the door

Experience Stream

Most of you, when you’re teaching yourself, have learned a program that says, well, what did we write when we took the sum of the elements of an array? Generally speaking, it goes like this:

public static void main(String[] args) {
    int[] nums = { 1.2.3 };
    int sum = 0;
    for (int i : nums) {
        sum += i;
    }
    System.out.println("Results are:" + sum);
}
Copy the code

If we were using a Stream, we could do this:

public static void main(String[] args) {
    int[] nums = { 1.2.3 };
    int sum2 = IntStream.of(nums).sum();
    System.out.println("Results are:" + sum2);
}
Copy the code

As you can see from the amount of code, the Stream approach is less.

Some scenarios often use operations (summing/de-replicating/filtering….) Etc.), has encapsulated the API for you, you don’t write, I provide you with the API is good.

1.1 Concurrency

Back to our original code:

public static void main(String[] args) {
    int[] nums = { 1.2.3 };
    int sum = 0;
    for (int i : nums) {
        sum += i;
    }
    System.out.println("Results are:" + sum);
}
Copy the code

If we want to support concurrency internally in a for loop, it’s not easy to write. But parallel can be supported by calling a method using a Stream:

public static void main(String[] args) {
    int[] nums = { 1.2.3 };
    int sum2 = IntStream.of(nums).parallel().sum();
    System.out.println("Results are:" + sum2);
}
Copy the code

Advantages: Tuning API is certainly less than their own code.

Disadvantages: not very convenient debugging

In my opinion, there are two reasons to use Stream:

  • Convenient concurrent
  • Small amount of code (direct API calls)

How to use a Stream?

There are three steps to using Stream:

  1. Create the Stream flow
  2. Perform intermediate operations through the Stream object
  3. Perform the final operation and get the result

2.1 create a flow

The most common way to create a flow is to create a flow from a collection

/** * returns all stream objects *@param args
 */
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    // Create from the collection
    Stream<String> stream = list.stream();
    Stream<String> stream1 = list.parallelStream();

    // Create from an array
    IntStream stream2 = Arrays.stream(new int[] {2.3.5});

    // Create a digital stream
    IntStream intStream = IntStream.of(1.2.3);

    // Create with random
    IntStream limit = new Random().ints().limit(10);

}
Copy the code

2.2 Performing Intermediate Operations

How to understand intermediate operations? We can create a Stream from above. If we operate on a Stream and return a Stream after a Stream operation, we call this operation intermediate.

For example, we now have the string my Name is 007, as follows:

String str = "my name is 007";

Stream.of(str.split("")).filter(s -> s.length() > 2)
    .map(s -> s.length()).forEach(System.out::println);
Copy the code

Break down:

Create a stream object from a string array:

Stream<String> split = Stream.of(str.split(""));
Copy the code

Filter () {filter ();}

Stream<String> filterStream = split.filter(s -> s.length() > 2);
Copy the code

3, Perform the intermediate operation (map) on the stream object, return the stream object again:

Stream<Integer> integerStream = filterStream.map(s -> s.length());
Copy the code

Since all intermediate operations return stream objects, we can make chain calls.

Note: Operations on Stream are not performed immediately, but only when the user actually needs the result (lazy evaluation).

For example, peek() is an intermediate operation that returns a Stream object, and as long as it does not perform the final operation, the Stream will not be executed.

String str = "my name is 007";
Stream.of(str.split("")).peek(System.out::println); // No information will be printed
Copy the code

2.3 Performing the Final Operation

The Stream object is no longer returned by the final operation. The Stream will not be executed until the method of the final operation is called. Again, take the above example:

String str = "my name is 007";
Stream.of(str.split("")).peek(System.out::println).forEach(System.out::println)
Copy the code

This time we added the final operation, so this time the Stream will be executed. Since both the intermediate operation and the final operation print, we will see two prints:

As for the difference between intermediate and final operations, we can just look at the return value. The intermediate operation returns a Stream instance, and the final operation does not return a Stream instance:

The last

This article is mainly to give you a preliminary understanding of the Stream Stream. As for the intermediate operation, I will not write the API explanation of the final operation (there are many online tutorials).

I think there are two reasons to use Stream:

  1. The JDK library provides existing apis, and the code is concise and optimized
  2. Facilitate concurrency. You can remember a conclusion: inmulticoreIn case, it can be usedparallelStream API to take advantage of multiple cores. In the case of a single core, we wrote it ourselvesforPerformance is not much worse than the Stream API

References:

  • Flow manipulation in Java8 – basic usage & performance testing
  • Java 8 Stream code, you can read it?

Happy to export dry Java technology public number: Java3y. The public account has more than 200 original technical articles, massive video resources, beautiful brain map, attention can be obtained!

Think my article is good, give it a thumbs up!