I have been writing middleware related code and providing SDK for business parties to use, but many business parties still stay at version 1.7 and do not upgrade. For compatibility, I dare not use some new features of Java8, such as Stream, in the code. Although it cannot be used, I still need to learn.

What is the Stream

Stream is a new feature added to Java 8 and is a completely different concept from InputStream and OutputStream in the java.io package. With the help of Lambda expressions, it allows you to process data in a declarative way, which can greatly improve the productivity of Java programmers, allowing programmers to write efficient, clean and concise code.

Stream Demo

Go straight to the Demo and get a feel for it

List<String> myList = Arrays.asList("a"."b"."c"."d"."e"); myList.stream() .filter(s -> s.startsWith("1"))    .map(String::toUpperCase)    .sorted()    .forEach(System.out::println);
Copy the code

How Stream works

When working with a stream, there are usually three basic steps:

  • Get a data source

  • Data conversion

  • Perform operations to obtain desired results

Each conversion does not change the original Stream object, but returns a new Stream object (which can have multiple conversions), which allows operations on it to be arranged like a chain to become a pipe, as shown in the figure below.

In Stream, there are two operations

  • In the middle of operation

  • End of operation

An intermediate operation returns a Stream, a terminal operation returns a void or non-stream result. In the demo, filter, map, and sorted are intermediate operations, while forEach is an end operation.

How a Stream is generated

There are many ways to create streams, the most common being from Collections, lists, and sets

List<String> myList = Arrays.asList("a1"."a2"."b1"."c2"."c1"); Stream<String> stream = myList.stream()Copy the code

Calling the stream() method on the object myList returns a regular object stream.

It can also be generated from a bunch of known objects.

Stream<String> stream  = Stream.of("a1"."a2"."a3")
Copy the code

Of course, there are other ways:

  • Collection.stream()

  • Collection.parallelStream()

  • BufferedReader.lines()

  • Files.walk()

  • BitSet.stream()

  • Random.ints()

  • JarFile.stream()

  • .

Normal operation

forEach

The forEach method receives a Lambda expression that iterates through each data in the stream

Stream.of(1, 2, 3).forEach(System.out::println); / / 1 / / 2 / / 3Copy the code

map

A map is used to map each element to the corresponding result

Stream.of(1, 2, 3).map( i -> i*i).forEach(System.out::println); / / 1 / / 4 / / 9Copy the code

filter

Filter is used to filter out elements by the set criteria

Stream.of(1, 2, 3).filter( i -> i == 1).forEach(System.out::println); / / 1Copy the code

limit

Limit is used to obtain a specified number of streams

Stream.of(1, 2, 3, 4, 5).limit(2).forEach(System.out::println); / / 1 / / 2Copy the code

sorted

Sorted is used to sort convection

Stream.of(4, 1, 5).sorted().forEach(System.out::println); / / 1 / / 4 / / 5Copy the code

Match

There are three match methods, semantically speaking:

  • AllMatch: All elements of the Stream match the predicate passed in, which returns true

  • AnyMatch: Returns true as long as one element of the Stream matches the predicate passed in

  • NoneMatch: None of the elements in the Stream match the passed predicate, which returns true

Neither of them has to traverse the entire element to return a result. For example, allMatch skips all remaining elements as long as one element does not meet the criteria and returns false.

boolean result = Stream.of("a1"."a2"."a3").allMatch(i -> i.startsWith("a")); System.out.println(result); //true
Copy the code

reduce

The reduce method accumulates a sequence of elements to a value based on a specified function. This method takes two arguments:

  • The starting value

  • Accumulator function.

If YOU have a List, you want to get the sum of all of these elements and some initial values.

int result = Stream.of(1, 2, 3).reduce(20, (a,b) -> a + b); System.out.println(result); / / 26Copy the code

collect

The Collectors class provides rich tools and methods

  • toList

  • toSet

  • toCollection

  • toMap

  • .

All these methods need to be passed in through the collect method.

Set<Integer> result = Stream.of(1, 1, 2, 3).collect(Collectors.toSet()); System.out.println(result); / / [1, 2, 3]Copy the code

Collect can turn a Stream into a Collection object,

SAO skills

The for loop

In addition to the regular Stream object, there are special types of streams that handle basic data types int, long, and double: IntStream, LongStream, and DoubleStream.

For example, intstream.range () can be used instead of the regular for loop.

IntStream.range(1, 4).forEach(System.out::println);
Copy the code

The random number

Random’s INTS method can return a stream of Random data, such as 10 Random numbers ranging from 1 to 100.

Random random = new Random(); random.ints(1, 100).limit(10).forEach(System.out::println);Copy the code

Case conversion

List<String> output = wordList.stream()  .map(String::toUpperCase)  .collect(Collectors.toList());
Copy the code

The Stream characteristics

In short, the characteristics of Stream can be summarized as follows:

There is no storage

A Stream is not a data structure; it is just a view of some data source

security

Any modification to the Stream does not modify the data source behind it. For example, filtering a Stream does not delete the filtered element, but instead produces a new Stream without the filtered element.

Idle run

Operations on Stream are not performed immediately, but only when the user actually needs the result.

A one-time

A Stream can only be “consumed” once and is invalidated once iterated, just like a container’s iterator, which must be regenerated to iterate again.

lambda

All Stream operations must take lambda expressions as arguments