Source: Jane books | author: litesky links: www.jianshu.com/p/11c925cdb…

preface

I believe that The Java8Stream has been heard of, but you may not be able to use it or not familiar with it. I will take you to the top of the Stream in the “Playing with Java8Stream” series of articles.

The operator

What is an operator? Operator is a kind of processing of data, a processing program; It’s like a factory worker performing a process on an assembly line.

The Stream operators are roughly divided into two types: intermediate operators and termination operators

Intermediate operator

In the case of data flows, the data flow can still be passed to the lower-level operator after the intermediate operator executes the formulation handler.

There are eight types of intermediate operators (excluding parallel,sequential, which do not involve processing a data stream) :

  1. Map (mapToInt mapToLong, mapToDouble) conversion operators, such as A – > B, the default here provides an int, long, double operators.
  2. Flatmap (flatmapToInt flatmapToLong, flatmapToDouble) the pat down operations such as int [] {4} 2 pat down into 2 and 4 is one from the original data into three, This provides operators to flatten int,long,double by default.
  3. For example, if there are 10 data streams, I only need to send the first 3 to use them.
  4. Distint removes duplicate elements from the distint operation, using equals at the bottom.
  5. Filter Indicates the operation to filter unwanted data.
  6. Peek pick out operation. If you want to perform some operations on data, such as reading, editing, and so on.
  7. Skip Skip operations, skip certain elements.
  8. Sorted (unordered) sorts elements, provided that the Comparable interface is implemented. You can also customize the comparator.

Terminating operator

When data is processed in the middle, it is the turn of the termination operator. Terminating operators are used to collect or consume data. Data does not flow down after terminating operations. Terminating operators can only be used once.

  1. Collect Collect all data. This operation is very important. The official Collectors provide many Collectors, and the core of the Stream is Collectors.
  2. Count Indicates the final number of data counted.
  3. FindFirst, findAny find operations, find the first, findAny return type Optional.
  4. NoneMatch, allMatch, anyMatch match operation, whether the data flow has matching elements The return value is bool.
  5. Min, Max maximum value operation, need to define the comparator, return the maximum and minimum value in the data flow.
  6. Reduce protocol operation. The value of the entire data flow is reduced to one value. Count, min, and Max use Reduce.
  7. ForEach and forEachOrdered traversal operations, where the final data is consumed.
  8. ToArray array operation to convert elements of a data stream to an array.

I’m only covering Stream here, not IntStream, LongStream, and DoubleStream, which implement some special operators that I’ll cover in a future article.

Having said that, these operators are not enough; As the saying goes, the proof is in the pudding. So, Let’s go.

Code to rehearse

A Stream sequence of operations must use termination operations, otherwise the entire data Stream will not flow, that is, the processing operation will not be executed.

  • The map operator asks for a Function that converts type T to type R.

The map operation converts the original word to the length of each single, using the String’s own length() method, which returns type int. I’m using lambda expressions directly here, but I leave lambda expressions to the reader.

public class Main { public static void main(String[] args) { Stream.of("apple","banana","orange","waltermaleon","grape") .map(e->e.length())) int. ForEach (e-> system.out.println (e)); // output}}Copy the code

Of course, member function references are used here, but for readers’ convenience, the following examples will use lambda expressions instead of function references.

public class Main { public static void main(String[] args) { Stream.of("apple","banana","orange","waltermaleon","grape") .map(String::length) // The length of the word int. ForEach (system.out ::println); }}Copy the code

The result is shown below:

  • MapToInt converts elements in a data stream to ints. This defines the type of the conversion, resulting in an IntStream, and the result can only be converted to ints.

public class Main { public static void main(String[] args) { Stream.of("apple", "banana", "orange", "waltermaleon", ForEach (e -> system.out.println (e)); }}Copy the code

MapToInt as shown in figure:

  • MapToLong, mapToDouble and mapToInt are similar
public class Main { public static void main(String[] args) { Stream.of("apple", "banana", "orange", "waltermaleon", ForEach (e -> system.out.println (e)); forEach(e -> system.out.println (e)); }}Copy the code

MapToLong as shown in figure:

public class Main { public static void main(String[] args) { Stream.of("apple", "banana", "orange", "waltermaleon", ForEach (e -> system.out.println (e)); forEach(e -> system.out.println (e)); }}Copy the code

MapToDouble as shown in figure:

  • The function of flatmap is to flatten elements, rebuild the flattened elements into streams, and merge these streams into a Stream serially

public class Main { public static void main(String[] args) { Stream.of("a-b-c-d","e-f-i-g-h") .flatMap(e->Stream.of(e.split("-"))) .forEach(e->System.out.println(e)); }}Copy the code

Flatmap is shown in figure:

  • FlatmapToInt, flatmapToLong, flatmapToDouble, and flatMap are all similar, except that the types are limited.

  • Limit limits the number of elements. Simply pass in a long to indicate the maximum number of elements

Public class Main {public static void Main (String[] args) {stream.of (1,2,3,4,5,6).limit(3 .forEach(e->System.out.println(e)); // the first three 1,2,3}}Copy the code

Limit as shown in figure:

  • Distinct is determined by equals. If you want to override the equals method, you need to override the equals method, but this is not the only method. I will show you how to implement this method in a later article.

Public class Main {public static void Main (String [] args) {Stream. Of,2,3,1,2,5,6,7,8,0,0,1,2,3,1 (1). Distinct () / / to heavy .forEach(e->System.out.println(e)); }}Copy the code

Distinct as shown in figure:

  • Filter Filters certain elements. Those that do not meet the filtering criteria cannot enter the downstream of the stream
Public class Main {public static void Main (String [] args) {Stream. Of,2,3,1,2,5,6,7,8,0,0,1,2,3,1 (1). The filter (e - > e > = 5) ForEach (e-> system.out.println (e)); }}Copy the code

The filter is shown in figure:

  • Peek selects elements, which can be understood as advance consumption
public class Main { public static void main(String[] args) { User w = new User("w",10); User x = new User("x",11); User y = new User("y",12); Stream.of(w,x,y) .peek(e->{e.setName(e.getAge()+e.getName()); }) // change the name to age + name.foreach (e-> system.out.println (e.tostring ())); // change the name to age + name.foreach (e-> system.out.println (e.tostring ())); } static class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; }}}Copy the code

Peek as shown in figure:

  • Skip element
Public class Main {public static void Main (String[] args) {stream.of (1,2,3,4,5,6,7,8,9).skip(4 .forEach(e->System.out.println(e)); // the output should only be 5,6,7,8,9}}Copy the code

The skip as shown in figure:

  • Sorted relies on the Comparable implementation at the bottom and can also provide a custom comparator

Here Integer implements the comparator

Public class Main {public static void Main (String[] args) {stream.of (2,1,3,6,4,9,6,8,0).sorted() .forEach(e->System.out.println(e)); }}Copy the code

The sorted default comparator looks like this:

Custom comparisons are used here, and of course User can implement the Comparable interface

public class Main {

    public static void main(String[] args) {

        User x = new User("x",11);
        User y = new User("y",12);
        User w = new User("w",10);

        Stream.of(w,x,y)
                .sorted((e1,e2)->e1.age>e2.age?1:e1.age==e2.age?0:-1)
                .forEach(e->System.out.println(e.toString()));

    }

    static class User {

        private String name;

        private int age;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

}

Copy the code

As shown in figure:

  • Collect the final data flow into the List, Set, and Map containers using the collector provided by the system.

Here I use Collect to collect elements into a set

public class Main { public static void main(String[] args) { Stream.of("apple", "banana", "orange", "waltermaleon", ForEach (e -> system.out.println (e)); forEach(e -> system.out.println (e)); }}Copy the code

Yi? The forEach operator can only be used once. ForEach is not only a Stream operator, but also a syntactic candy in various collections.

public class Main { public static void main(String[] args) { Set<String> stringSet = Stream.of("apple", "banana", "orange", "waltermaleon", "grape") .collect(Collectors.toSet()); // Set stringset.foreach (e-> system.out.println (e)); Set syntax sugar forEach}Copy the code

The result is shown below:

  • Count counts the number of elements in the data stream and returns type long
public class Main { public static void main(String[] args) { long count = Stream.of("apple", "banana", "orange", "waltermaleon", "grape") .count(); System.out.println(count); }}Copy the code

The count is shown in figure:

  • FindFirst retrieves the first element in the stream

Here we find the first element, apple

public class FindFirst { public static void main(String[] args) { Optional<String> stringOptional = Stream.of("apple", "banana", "orange", "waltermaleon", "grape") .findFirst(); stringOptional.ifPresent(e->System.out.println(e)); }}Copy the code

The findFirst result is shown below:

  • FindAny gets any element in the stream
public class FindAny { public static void main(String[] args) { Optional<String> stringOptional = Stream.of("apple", "banana", "orange", "waltermaleon", "grape") .parallel() .findAny(); String optional. ifPresent(e-> system.out.println (e)); }}Copy the code

FindAny uses results in parallel streams:

Output the orange

Output the banana

  • None of the elements in the noneMatch data stream matches the condition

There is no element equal to aa in the data stream, but aa exists in the stream, so the final result should be false

public class NoneMatch { public static void main(String[] args) { boolean result = Stream.of("aa","bb","cc","aa") .noneMatch(e->e.equals("aa")); System.out.println(result); }}Copy the code

NoneMatch as shown in figure:

  • AllMatch and anyMatch one is a full match and one is an arbitrary match similar to noneMatch, I won’t give you any examples here.
  • The one with the smallest min, passed to the comparator, or not (if the data stream is empty)
public class Main { public static void main(String[] args) { Optional<Integer> integerOptional = ,9,8,4,5,6 Stream of (0, 1), min (pareTo (e1 and e2) - > e1.com (e2)); integerOptional.ifPresent(e->System.out.println(e)); }Copy the code

Min as shown in figure:

  • The largest of the Max elements, which requires a comparator, or none (when the stream is Empty)
public class Main { public static void main(String[] args) { Optional<Integer> integerOptional = ,9,8,4,5,6 Stream of (0, 1). The Max (pareTo (e1 and e2) - > e1.com (e2)); integerOptional.ifPresent(e->System.out.println(e)); }}Copy the code

Max is shown in figure:

  • Reduce is a specification operation where all elements are reduced to one, such as summation, multiplication, etc.

Here an addition is implemented, specifying the initialized value

Public class Main {public static void Main (String[] args) {int sum = stream.of (0,9,8,4,5,6,-1) .reduce(0,(e1,e2)->e1+e2); System.out.println(sum); }}Copy the code

Reduce as shown in figure:

  • forEach

ForEach has actually seen this before, iterating over each data

  • ForEachOrdered is suitable for iteration in the case of parallel flows to ensure the order of iteration

So we’re going to print the numbers in parallel

Public class ForEachOrdered {public static void main(String[] args) {stream.of (0,2,6,5,4,9,8,-1).parallel() .forEachOrdered(e->{ System.out.println(Thread.currentThread().getName()+": "+e); }); }}Copy the code

ForEachOrdered as shown in figure:

  • ToArray converts to an array and can provide a custom array generator
Public class ToArray {public static void main(String[] args) {Object[] objects= stream.of (0,2,6,5,4,9,8,-1).toarray ();  for (int i = 0; i < objects.length; i++) { System.out.println(objects[i]); }}}Copy the code

ToArray as shown in figure:

conclusion

If you can follow my article to type through each example, you will be able to grasp the initial use of these operators; I’ll take you step by step into Stream in future articles.

The last

If you like the article, you can click a “like”. Finally, we will recommend a high-quality technology-related article every day, mainly sharing Java related technology and interview skills, learning Java without getting lost.