[Java Notes] Stream API

There are two of the most important changes in Java 8. The first is a Lambda expression; the other is the Stream API

The Stream API (java.util.stream) brings a true functional programming style to Java. This is by far the best complement to the Java class library, because the Stream API can greatly improve the productivity of Java programmers, allowing programmers to write more efficient, clean, and concise code

To put it bluntly, Stream is a data channel, used to manipulate the sequence of elements generated by the data source (collection, array, etc.).

content

The difference between Stream and Collection

Notes on using Stream

Three steps of Stream operation

instantiation of Stream

Intermediate operation of Stream

Stream termination operation

The difference between Stream and Collection

Collection is a static in-memory data structure, while Stream is about computation. The former is mainly oriented to memory and stored in memory, while the latter is mainly oriented to CPU and realizes calculation through CPU

Notes on using Stream

1. Stream itself does not store elements

2. Stream does not mutate the source object. Instead, they return a new Stream holding the result

3. Stream operations are performed lazily. This means they will wait until the result is needed before executing

Three steps of Stream operation

1. Create Stream

a data source (collection, array, etc.), get a stream

2. Intermediate operations

An intermediate operation chain that processes data from the data source

3. Terminate the operation

Once the terminating operation is executed, the chain of intermediate operations is executed and the result is produced. After that, it will not be used again

instantiation of Stream

import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class StreamTest {
    //Method 1: Create through a collection
    @Test
    public void test() {
        List list = new ArrayList();
        list.add(1);
        list.add(4);
        list.add(7);
        list.add(9);
        //default Stream stream(): returns a sequential stream
        Stream stream = list.stream();
        //default Stream parallelStream(): returns a parallel stream
        Stream parallelStream = list.parallelStream();
    }
    //Method 2: Through the array
    @Test
    public void test2(){
        int[] arr = new int[]{1,2,3,5,6,8};
        //Calling static Stream stream(T[] array) of class Arrays: returns a stream
        IntStream stream = Arrays.stream(arr);
    }
    //Method 3: Through of() of Stream
    @Test
    public void test3(){
        Stream<Integer> stream = Stream.of(1,3,4,5,7,8);
    }
    //Method 4: Create an infinite stream
    @Test
    public void test4(){
        //iterate
        //public static Stream iterate(final T seed,final UnaryOperator<T> f)
        Stream.iterate(0,t -> t + 2).limit(10).forEach(System.out::println);
        //generate
        //public static Stream generate(Supplier<T> s)
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    }
}

Intermediate operation of Stream

Multiple intermediate operations can be connected to form a pipeline, and the intermediate operations will not perform any processing unless a termination operation is triggered on the pipeline. And do it all at once when the operation is terminated, called "lazy evaluation"

filter(Predicate)Filter out elements whose result is false
map(fun)Convert the value of an element, using method arguments or lambda expressions
flatMap(fun)If the element is a stream, flatten the stream into normal elements, and then perform element conversion
imit(n)keep the first n elements
skip(n)skip the first n elements
distinct()remove duplicate elements
sorted()Sorts a stream of Comparable elements
sorted(Comparator)Sort stream elements by Comparator
peek(fun)The flow is unchanged, but each element is passed to fun for execution, which can be used for debugging
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamTest {
    @Test
    public void test() {
        List list = new ArrayList();
        list.add(1);
        list.add(4);
        list.add(9);
        list.add(7);
        //default Stream stream(): returns a sequential stream
        Stream stream = list.stream();
        //Query for values ​​greater than 5
        stream.filter(l -> l.hashCode() > 5).forEach(System.out::print);
        System.out.println();
        //Truncates the stream so that it does not exceed the specified number of elements
        list.stream().limit(3).forEach(System.out::print);
        System.out.println();
        //Skip elements, returning a stream with the first n elements thrown away
        list.stream().skip(3).forEach(System.out::print);
        System.out.println();
        //Filter to remove duplicate elements by hashCode() and equals() of elements generated by the stream
        list.add(1);
        list.stream().distinct().forEach(System.out::print);
        System.out.println();
        //map(Function f) accepts a function as a parameter to convert elements into other forms or extract information
        List<String> list1 = Arrays.asList("aa","bb","cc");
        list1.stream().map(str -> str.toUpperCase()).forEach(System.out::print);
        System.out.println();
        //Sorting: sorted() natural sorting
        list.stream().sorted().forEach(System.out::print);
    }
}

>>> 97
    149
    7
    1497
    AABBCC
    11479

Stream termination operation

Terminate operations produce results from the stream's pipeline. The result can be any value that is not a stream

After the stream has been terminated, it cannot be used again

max(Comparator)

min(Comparator)

count()

findFirst()return the first element
findAny()return any element
anyMatch(Predicate)Returns true if any element matches
allMatch(Predicate)Returns true if all elements match
oneMatch(Predicate)Returns true if no elements match
reduce(fun)Calculate some value from the stream, accept a binary function as the accumulator, apply it continuously starting from the first two elements, the intermediate result of the accumulator as the first argument, and the stream elements as the second argument
reduce(a, fun)a is the unitary value, which is the starting point of the accumulator
reduce(a, fun1, fun2)Similar to binary deformation, in concurrent operations, when the first and second parameters of the accumulator are both stream element types, the accumulator can also be applied to each intermediate result for merging, but when the first parameter of the accumulator is When the parameter is not a stream element type but is of type T, each intermediate result is also of type T, and fun2 is required to combine the intermediate results

iterator()

forEach(fun)

forEachOrdered(fun)Can be applied on parallel streams to preserve element order

toArray()

toArray(T[ ] :: new)returns the correct element type

collect(Collector)

collect(fun1, fun2, fun3)fun1 converts stream elements; fun2 is an accumulator, which accumulates the conversion results of fun1; fun3 is a combiner, which combines the results of the accumulator in the parallel processing process

Collectors: 

import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class StreamTest {
    @Test
    public void test() {
        List<Integer> list = new ArrayList();
        list.add(1);
        list.add(4);
        list.add(9);
        list.add(7);
        //Are all numbers greater than 5
        boolean allMatch = list.stream().allMatch(l -> l.hashCode() > 5);
        System.out.println(allMatch);
        //Is there anything greater than 5
        boolean anyMatch = list.stream().anyMatch(l -> l.hashCode() > 5);
        System.out.println(anyMatch);
        //Check if there are no matching elements
        boolean noneMatch = list.stream().noneMatch(l -> l.hashCode() > 5);
        System.out.println(noneMatch);
        //return the first element
        Optional l = list.stream().findFirst();
        System.out.println(l);
        //return the smallest number
        Optional l1 = list.stream().max((l4,l3) -> Double.compare(l4.hashCode(),l3.hashCode()));
        System.out.println(l1);
        //internal iteration
        list.stream().forEach(System.out::print);
        System.out.println();
        //reduce() can repeatedly combine elements in a stream to get a value
        //Calculate the sum
        Integer sum1 = list.stream().reduce(0, Integer::sum);
        System.out.println(sum1);
        //Find values ​​greater than 5, return a List or Set
        List<Integer> collect = list.stream().filter(l6 -> l6 > 5).collect(Collectors.toList());
        System.out.print(collect);
    }
}

>>> false
    true
    false
    Optional[1]
    Optional[9]
    1497
    21
    [9, 7]

Tags: Java OOP programming language

Posted by Jeannie109 on Thu, 05 May 2022 00:41:54 +0300