Java Stream API

[TOC]

In Java8, Steam can be defined as a sequence of elements from a source, while Streams supports aggregation of elements, which refers to collections and arrays of data that provide data for a stream

Before we start working with Streams, we should know that the Streams API works directly with Streams, so we’ll create a Steam first.

At the level of granularity, the difference between a Collection and a Stream has to do with when things are evaluated. A Collection is an in-memory data structure in which all the values that the data structure is considered to have currently. Each element in the collection must be evaluated before it can be added to the collection. A Stream is conceptually a pipe in which elements are evaluated on demand.

This concept brings significant programming advantages. The idea is that users will only extract the values they need from the Stream, and these elements will only be generated (invisible to the user) when they are needed. This is a form of producer-consumer relationship.

In Java, java.util.stream represents a Stream on which one or more operations can be performed. Stream operations are either intermediate or terminal.

The terminal operation returns a specific type of result and the intermediate operation returns the stream itself, so we can chain multiple methods in a row to perform the operation in multiple steps.

Streams are created on the source, such as java.util.Collection likes lists or sets. In Map not directly supported, we can create mapping keys, values.

Stream operations can be performed sequentially or in parallel. When executed in parallel, it is called a parallel flow

1. Create flow

Here are some ways to create a flow

1.1 the Stream of ()
 public static void main(String[] args)
     {
         // Get a data Stream using the stream. of method
         Stream<Integer> stream = Stream.of(1.2.3.4.5.6.7.8.9);
         stream.forEach(p -> System.out.println(p));
     }
Copy the code
1.2 stream.of (Array)

We can generate a stream by introducing an array

public static void main(String[] args)
     {
         Stream<Integer> stream = Stream.of( new Integer[]{1.2.3.4.5.6.7.8.9}); stream.forEach(p -> System.out.println(p)); }Copy the code
1.3 Lists. Steam (common)

In our work, we often use a collection to fetch a stream, and the elements in the stream come from a List

public static void main(String[] args)
     {
         List<Integer> list = new ArrayList<Integer>();
 
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
 
         Stream<Integer> stream = list.stream();
         stream.forEach(p -> System.out.println(p));
     }
Copy the code
1.4 stream.generate () or stream.iterate ()

// In the following code, we create a stream from the given element, but we only limit to get 20, so we use the limit

 public static void main(String[] args)
     {
         Stream<Integer> randomNumbers = Stream
             .generate(() -> (new Random()).nextInt(100));
 
         randomNumbers.limit(20)
              .forEach(System.out::println);
     }

Copy the code

1.5 String Character stream

public static void main(String[] args)
     {
        IntStream stream = "12345_abcdefg".chars();
        stream.forEach(p -> System.out.println(p));
         
    //OR
         
        Stream<String> stream = Stream.of("A$B$C".split(\ \ "$"));
        stream.forEach(p -> System.out.println(p));
     
Copy the code

1.6 Stream. Builder ()

Create a builder by creating a Builder method, which also generates the flow

Stream<Object> name = Stream.builder().add("name").build();
Copy the code

2. Stream Collector

After performing middleware operations on elements in the flow, we can use the flow collector method to collect the processed elements again into a collection

2.1 Collect elements from stream into a collection

In the given example, first we create a stream on the integers 1 through 10. Then we process the stream elements to find all the even numbers. Finally, collect all the even numbers into a set

 public static void main(String[] args)
     {
         List<Integer> list = new ArrayList<Integer>();
 
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
 
         Stream<Integer> stream = list.stream();
         List<Integer> evenNumbersList = stream.filter(i -> i%2= =0)
                                                .collect(Collectors.toList());
         System.out.print(evenNumbersList);
     }

Copy the code
2.2 Collect elements from stream into an array

As with the requirement in the previous example, this time we collect even numbers into an array

List<Integer> result = new ArrayList<>();
		for (Integer x : list) {
			if (x % 2= =0) {
				result.add(x);
			}
		}

Integer[] evenNumbersArr = list.stream().filter(x -> x% 2= =0).toArray(Integer[]::new);



Copy the code

Of course, the flow collector can not only collect lists, but also sets and maps, which can be called by Collectors

3. The flow operation

Operations on streams are divided into two types: intermediate flow operations and terminal operations

  • The intermediate stream operation returns a Steam stream,

  • Terminal operation Directly processes the data in six after the operation, with no return value

    List<String> memberNames = newArrayList<>(); memberNames.add("Amitabh"); memberNames.add("Shekhar"); memberNames.add("Aman"); memberNames.add("Rahul"); memberNames.add("Shahrukh"); memberNames.add("Salman"); memberNames.add("Yana"); memberNames.add("Lokesh");
    Copy the code
3.1.1 stream.filter (Filter)
The filter operation takes A method of type Predicate and returns A Steam stream that meets the requirements of the Predicate, such as the city starting with A from the set aboveCopy the code
memberNames.stream().filter((s) -> s.startsWith("A"))                    .forEach(System.out::println);
Copy the code
3.1.2 stream.map (Transform, map)

I think of a map operation as a transformation or mapping operation, such as converting all lowercase characters in a collection to uppercase characters

memberNames.stream().filter((s) -> s.startsWith("A"))                    .map(String::toUpperCase)                    .forEach(System.out::println);
Copy the code
3.1.3 stream. sorted

The sort interface allows you to sort the elements of a collection directly. Before Java 8, we had to sort the elements of a list. We had to use sort and use the anonymous inner class Compare

memberNames.sort(new Comparator<String>() {			@Override			public int compare(String o1, String o2) {				return 0; }});Copy the code

But now with Java 8, we can sort in a different way

memberNames.stream().sorted()                    .map(String::toUpperCase)                    .forEach(System.out::println);
Copy the code

The default is forward sorting. If you want to reverse sorting, you can use the Reverse method to change the order

3.2 Terminal Operations

Terminal operations return the result of terminal operations,

3.2.1 Stream. Foreach

Foreach is an iterated feature

memberNames.forEach(System.out::println);
Copy the code
3.2.2 collect collect

Collect is a collection method that takes matching data from a Stream and stores it in a collection

List<String> memNamesInUppercase = memberNames.stream().sorted()                            .map(String::toUpperCase)                            .collect(Collectors.toList());         System.out.print(memNamesInUppercase);
Copy the code
3.2.3 match match

Match is a general term for the method of match class. It is similar to the filter mentioned before, but with a slightly stronger function and more methods

Trueboolean matchedResult = membernames.stream ().anymatch ((s) -> s.startswith ("A")); System.out.println(matchedResult); TruematchedResult = membernames.stream ().allMatch((s) -> s.startswith ("A")); TruematchedResult = membernames.stream (). System.out.println(matchedResult); TruematchedResult = membernames.stream ().nonematch ((s) -> s.startswith ("A")); System.out.println(matchedResult);
Copy the code
4.2.4. Stream. The count ()

Count a terminal operation that returns a value of type long

long totalMatched = memberNames.stream()    .filter((s) -> s.startsWith("A"))    .count(); System.out.println(totalMatched);
Copy the code
4.2.5. Stream. The reduce ()

Reduce means to reduce the value of stream to a final result according to the specified calculation model.

A blogger article on this approach would be particularly good, with a reference to java8 reduce

The summary records the common operation methods for stream

In the middle of operation

  • filter
  • map
  • distinct
  • sorted
  • peek
  • limit
  • skip

Terminal operation

  • foreach
  • toArray
  • reduce
  • foreachOrdered
  • min
  • max
  • count
  • anyMatch
  • collect
  • Findfirst etc.