An overview,

Stream is a set of apis for working with arrays and collections. The Stream API provides an efficient and easy-to-use way to work with data. There are two reasons for the effort to introduce functional programming in Java 8:

  • Functional programming writes clean and purposeful code, and using the Stream interface lets you say goodbye to the for loop.
  • Multi-core friendly, Java functional programming has never been easier to write parallel programs; all you need is the parallel() method
  • Stream is the key abstraction for dealing with collections in Java8. It can specify what you want to do with collections, and can perform very complex operations like finding, filtering, and mapping data

2. Stream feature

1, not the data structure, no internal storage, will not save the data, so it can only be used once each Stream flow 2, 3 does not support index access, support parallel 4, it is easy to generate the data or collection (List, Set) 5, supports filtering, search, conversion, summary, aggregation operations such as 6, delayed calculation, flow process in the middle, The operation is logged and not executed immediately, and the actual calculation will not take place until the termination operation is executed

Three, classification,

There are two types of operations applied to a Stream:

  1. Intermediate: An Intermediate operation returns a Stream, so multiple Intermediate operations can be superimposed.
  2. Terminating operations are used to return the data we ultimately need. There can only be one terminating operation.

With the Stream Stream, we can clearly see what we are doing with a data set, which is very readable. And it’s easy to get parallel streams without having to write our own multithreaded code, which allows us to focus more on business logic.

Stateless:Refers to the processing of an element that is not affected by previous elements;Stateful:The operation cannot continue until all elements are retrieved.Non-short-circuit operation:Refers to having to process all elements to get the final result;Short circuit operation:Refers to meet certain eligible elements can get the final result, such as A | | B, if A is true, you do not need to judge the result of B.

Create a Stream

Stream. Generate method (iterate). Stream. Generate method (iterate)

4.1 Generate it from arrays

 // Generate it from an array
    static void gen1(a){
        String[] strs = {"a"."b"."c"."d"};
        Stream<String> strs1 = Stream.of(strs);// Use the static method in Stream: of()
        strs1.forEach(System.out::println);// Print out (a, b, c, d)
    }
Copy the code

4.2 Generate through collections

// Generate by collection
    static void gen2(a){
        List<String> list = Arrays.asList("1"."2"."3"."4");
        Stream<String> stream = list.stream();// Get a sequential stream
        stream.forEach(System.out::println);// print out (1,2,3,4)
    }
Copy the code

4.3 Create the Stream. Generate method

    //generate
    static void gen3(a){
        Stream<Integer> generate = Stream.generate(() -> 1);// Use the static method in Stream: generate()
        //limit returns a stream composed of the elements of the stream. The truncation length cannot exceed maxSize
        generate.limit(10).forEach(System.out::println);// Print the output (print 10 ones)
    }
Copy the code

4.4 Create it using the Stream. Iterate method

    / / use the iterator
    static void gen4(a) {
        Stream<Integer> iterate = Stream.iterate(1, x -> x + 1);// Use the static method in Stream: iterate()
        iterate.limit(10).forEach(System.out::println);// print out (1,2,3,4,5,6,7,8,9,10)
    }
Copy the code

4.4 Creating Other apis

// Other ways
    static void gen5(a){
        String str = "abcdefg";
        IntStream stream =str.chars();// get STR bytecode
        stream.forEach(System.out::println);// print out (97,98,99,100,101,102,103)
    }
Copy the code

Common APIS for Stream

5.1 Intermediate Operations

1. Filter: Filters certain elements in the stream
 // Intermediate operation: If the method is called and returns a Stream object, it is an intermediate operation
  Arrays.asList(1.2.3.4.5).stream()// Get the sequential stream
  .filter((x)->x%2= =0) / / 2, 4
  .forEach(System.out::println);

 // Find the sum of all the even numbers in the result set
 int count = Arrays.asList(1.2.3.4.5.6.7.8.9).stream()// Get the sequential stream
 .filter(x -> x % 2= =0).// 2 4 6 8 
 mapToInt(x->x).sum();/ / sum
 System.out.println(count); // Print out 20
Copy the code
2. Distinct: Remove duplicate elements by hashCode() and equals() of elements in the stream
 Arrays.asList(1.2.3.3.3.4.5.2).stream()// Get the sequential stream
 	.distinct()/ / to heavy
 	.forEach(System.out::println);// print out (1,2,3,4,5)
 
 System.out.println("De-weight: ---------------");
 
 Arrays.asList(1.2.3.3.3.4.5.2).stream()// Get the sequential stream
 	.collect(Collectors.toSet())/ / Set () to heavy
 	.forEach(System.out::println);// print out (1,2,3,4,5)

Copy the code
3. Sorting

Sorted () : Returns a stream composed of the elements of this stream, sorted in natural order. Sorted (Comparator com) : Returns a stream consisting of the elements of that stream, sorted by the provided Comparator.

// Get maximum and minimum values without using min and Max methods
   List<Integer> list = Arrays.asList(1.2.3.4.5.6);
   Optional<Integer> min = list.stream().sorted().findFirst();// Sort by number from smallest to largest
   System.out.println(min.get());// Print (1)
   
   Optional<Integer> max2 = list.stream().sorted((a, b) -> b - a).findFirst();// Timed sort sorts by the largest number
   System.out.println(max2.get());// Print out (6)

 // Sort by size (a-z)
 Arrays.asList("java"."c#"."python"."scala").stream().sorted().forEach(System.out::println);
 // Sort by length
 Arrays.asList("java"."c#"."python"."scala").stream().sorted((a,b)->a.length()-b.length()).forEach(System.out::println);
Copy the code
4. Capture

Skip (n) : After discarding the NTH element of the stream, paging can be realized with limit(n)

// Print 20-30 sets of data
      Stream.iterate(1,x->x+1).limit(50)// limit 50 总共到50
      .skip(20)// Skip the first 20
      .limit(10) // Print 10
      .forEach(System.out::println);/ / print (21,22,23,24,25,26,27,28,29,30)
Copy the code
5. Transform

Map: Takes as an argument a function that is applied to each element and maps it to a new element. FlatMap: Takes a function as an argument, replaces each value in the stream with another stream, and joins all streams into one stream.

List<String> list = Arrays.asList("a,b,c"."1, 2, 3");
 
// Convert each element to a new element without commas
Stream<String> s1 = list.stream().map(s -> s.replaceAll(",".""));
s1.forEach(System.out::println); // abc 123
 
Stream<String> s3 = list.stream().flatMap(s -> {
    // Convert each element to a stream
    String[] split = s.split(",");
    Stream<String> s2 = Arrays.stream(split);
    return s2;
});
s3.forEach(System.out::println); // a b c 1 2 3
Copy the code
6. Consumption

Peek: Like a map, you can get every element in the stream. But the map receives a Function expression that returns a value; Peek receives the Consumer expression and returns no value.

 // Print out each value in STR and calculate the final sum
 String str ="11,22,33,44,55";      
 System.out.println(Stream.of(str.split(",")).peek(System.out::println).mapToInt(Integer::valueOf).sum());//11 22 33 44 55 165
Copy the code

5.2 Terminating operations

1. Loop: forEach

The Users:

import java.util.Date;

/ * * *@program: lambda
 * @ClassName Users
 * @description:
 * @author: muxiaonong
 * @create: 11 * 2020-10-24@Version1.0 * * /
public class Users {

    private String name;
    public Users(a) {}

    / * * *@param name
     */
    public Users(String name) {
        this.name = name;
    }

    / * * *@param name
     * @return* /
    public static Users build(String name){
        Users u = new Users();
        u.setName(name);
        return u;
    }

    public String getName(a) {
        return name;
    }

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

    @Override
    public String toString(a) {
        return  "name='" + name + '\' '; }}Copy the code
   // Create a set of custom objects
   String str2 = "java,scala,python";
   Stream.of(str2.split(",")).map(x->new Users(x)).forEach(System.out::println);// Print output (name=' Java 'name='scala' name='python')
   Stream.of(str2.split(",")).map(Users::new).forEach(System.out::println);// Print output (name=' Java 'name='scala' name='python')
   Stream.of(str2.split(",")).map(x->Users.build(x)).forEach(System.out::println);// Print output (name=' Java 'name='scala' name='python')
   Stream.of(str2.split(",")).map(Users::build).forEach(System.out::println);// Print output (name=' Java 'name='scala' name='python')

Copy the code
2. Calculate: min, Max, count, sum

Min: minimum value of elements in the stream Max: maximum value of elements in the stream count: total number of elements in the stream sum: sum

 // Find the maximum value in the set
 List<Integer> list = Arrays.asList(1.2.3.4.5.6);
  Optional<Integer> max = list.stream().max((a, b) -> a - b);
  System.out.println(max.get()); / / 6
  // Select the minimum value of the set
  System.out.println(list.stream().min((a, b) -> a-b).get()); / / 1
 // Count the number of sets
 System.out.println(list.stream().count());/ / 6
  / / sum
  String str ="11,22,33,44,55";
  System.out.println(Stream.of(str.split(",")).mapToInt(x -> Integer.valueOf(x)).sum());
  System.out.println(Stream.of(str.split(",")).mapToInt(Integer::valueOf).sum());
  System.out.println(Stream.of(str.split(",")).map(x -> Integer.valueOf(x)).mapToInt(x -> x).sum());
  System.out.println(Stream.of(str.split(",")).map(Integer::valueOf).mapToInt(x -> x).sum());
Copy the code
3. Match: anyMatch, allMatch, noneMatch, findFirst, findAny

AnyMatch: Accepts a Predicate function that returns true as long as one element of the stream satisfies the Predicate, false allMatch otherwise: Receives a Predicate function that returns true only if every element in the stream matches the Predicate, or false noneMatch otherwise: Receives a Predicate function that returns true only if every element in the stream does not match the Predicate, false otherwise. FindFirst: returns the first element in the stream. FindAny: returns any element in the stream

List<Integer> list = Arrays.asList(1.2.3.4.5.6);
System.out.println(list.stream().allMatch(x -> x>=0)); // Returns true if the element in the collection is greater than or equal to 0
System.out.println(list.stream().noneMatch(x -> x > 5));// If the set has an element greater than 5. Returns false
System.out.println(list.stream().anyMatch(x -> x > 4));// If there are more than 44 elements in the set, return true
// Take the first even number
Optional<Integer> first = list.stream().filter(x -> x % 10= =6).findFirst();
System.out.println(first.get());/ / 6
// Pick an even number
Optional<Integer> any = list.stream().filter(x -> x % 2= =0).findAny();
System.out.println(any.get());/ / 2

Copy the code
4. Collectors: toArray and collect

Collector

is an interface with the following five abstract methods:
,>

  1. Supplier<A> supplier();Create A result container, A
  2. BiConsumer<A, T> accumulator();: consumable interface, the first argument is container A, the second argument is element T in the stream.
  3. BinaryOperator<A> combiner();Function interface. The function of this parameter is the same as combiner parameter in reduce. This parameter combines the running results of each child process in the parallel flow (container A after the accumulator function operation).
  4. Function<A, R> finisher();Function interface, parameter: container A, return type: collect method final result R.
  5. Set<Characteristics> characteristics();Returns an immutable Set that identifies the characteristics of the Collector
/ * * *@program: lambda
 * @ClassName Customer
 * @description:
 * @author: muxiaonong
 * @create: the 2020-10-24 hand *@Version1.0 * * /
public class Customer {

    private String name;

    privateInteger age; . Getset ignore}Copy the code
 public static void main(String[] args) {
        Customer c1 = new Customer("Zhang".10);
        Customer c2 = new Customer("Bill".20);
        Customer c3 = new Customer("Fifty".10);

        List<Customer> list = Arrays.asList(c1,c2,c3);

        / / to the list
        List<Integer> ageList = list.stream().map(Customer::getAge).collect(Collectors.toList());
        System.out.println("ageList:"+ageList);//ageList: [10, 20, 10]

        / / into the set
        Set<Integer> ageSet = list.stream().map(Customer::getAge).collect(Collectors.toSet());
        System.out.println("ageSet:"+ageSet);/ / ageSet: [20, 10]

// Convert to map. Note: The keys must be different; otherwise, an error will be reported
        Map<String, Integer> CustomerMap = list.stream().collect(Collectors.toMap(Customer::getName, Customer::getAge));
        System.out.println("CustomerMap:"+CustomerMap);//CustomerMap: {CustomerMap =20, CustomerMap =10, CustomerMap =10}

// String delimiter connection
        String joinName = list.stream().map(Customer::getName).collect(Collectors.joining(","."(".")"));
        System.out.println("joinName:"+joinName);//joinName :(zhang SAN, li si, wang wu)

// Aggregate operations
//1
        Long count = list.stream().collect(Collectors.counting());
        System.out.println("count:"+count);/ / count: 3
//2. Maximum age (same with minBy)
        Integer maxAge = list.stream().map(Customer::getAge).collect(Collectors.maxBy(Integer::compare)).get();
        System.out.println("maxAge:"+maxAge);/ / maxAge: 20

//3. Age of everyone
        Integer sumAge = list.stream().collect(Collectors.summingInt(Customer::getAge));
        System.out.println("sumAge:"+sumAge);/ / sumAge: 40

//4. Average age
        Double averageAge = list.stream().collect(Collectors.averagingDouble(Customer::getAge));
        System.out.println("averageAge:"+averageAge);/ / averageAge: 13.333333333333334

/ / group
        Map<Integer, List<Customer>> ageMap = list.stream().collect(Collectors.groupingBy(Customer::getAge));
        System.out.println("ageMap:"+ageMap);/ / ageMap: {20=[com.mashibing.stream.Customer@20ad9418], 10=[com.mashibing.stream.Customer@31cefde0, com.mashibing.stream.Customer@439f5b3d]}


/ / partition
// Divided into two parts, one is over 10 years old, the other is less than or equal to 10 years old
        Map<Boolean, List<Customer>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));
        System.out.println("partMap:"+partMap);

/ / code
        Integer allAge = list.stream().map(Customer::getAge).collect(Collectors.reducing(Integer::sum)).get();
        System.out.println("allAge:"+allAge);/ / allAge: 40


    }

Copy the code

Summary of Stream methods

Modifiers and types Methods and Instructions
static Collector<T,? ,Double> averagingDouble(ToDoubleFunction<? Super T> mapper) returns a Collector that produces the arithmetic mean of the two-valued function applied to the input element.
static Collector<T,? ,Double> averagingInt(ToIntFunction<? Super T> mapper) returns a Collector that produces the arithmetic mean of the integer value function applied to the input element.
static Collector<T,? ,Double> averagingLong(ToLongFunction<? Super T> mapper) returns a Collector that produces the arithmetic mean of the long-valued function applied to the input element.
static <T,A,R,RR> Collector<T,A,RR> CollectingAndThen (Collector<T,A,R> downstream, Function<R,RR> finisher) ADAPTS to the Collector for additional collation conversions.
static Collector<T,? ,Long> Counting () returns T of type Collector to count the number of input elements.
static <T,K> Collector<T,? ,Map<K,List>> groupingBy(Function<? super T,? Extends K> classifier) returns the Collector “implemented by the input element operation of the type on the group”, groups the elements according to the classification function, and in the returned result Map.
static <T,K,A,D> Collector<T,? ,Map<K,D>> groupingBy(Function<? super T,? extends K> classifier, Collector<? Super T,A,D> Downstream) returns A cascading T to the Collector “from the input element operation of the type on the group”, groups the elements according to the classification function, and then performs A reduction operation Collector of the values associated with the given key using the downstream specification.
static <T,K,D,A,M extends Map<K,D>>Collector<T,? ,M> groupingBy(Function<? super T,? extends K> classifier, Supplier mapFactory, Collector<? Super T,A,D> Downstream) returns A cascading T to the Collector “from the input element operation of the type on the group”, groups the elements according to the classification function, and then performs A reduction operation Collector of the values associated with the given key using the downstream specification.
static <T,K> Collector<T,? ,ConcurrentMap<K,List>> groupingByConcurrent(Function<? super T,? Extends K> classifier) returns a concurrent Collector implementation T “by the input element operation of the type on the group”, grouping elements according to the classification function.
static <T,K,A,D> Collector<T,? ,ConcurrentMap<K,D>> groupingByConcurrent(Function<? super T,? extends K> classifier, Collector<? Super T,A,D> Downstream) returns A concurrent Collector “cascading T” from the input element operation of the type on the group, grouping the elements according to the classification function, and then performing A reduction operation Collector of the values associated with the given key using the downstream specification.
static <T,K,A,D,M extends ConcurrentMap<K,D>> Collector<T,? ,M> groupingByConcurrent(Function<? super T,? extends K> classifier, Supplier mapFactory, Collector<? Super T,A,D> Downstream) returns A concurrent Collector “cascading T” from the input element operation of the type on the group, grouping the elements according to the classification function, and then performing A reduction operation Collector of the values associated with the given key using the downstream specification.
static Collector<CharSequence,? ,String> Joining () returns a Collector that joins the input elements to a String in the order they were encountered.
static Collector<CharSequence,? ,String> Joining (CharSequence Delimiter) returns a Collector that joins the input elements separated by the specified delimiter in the order encountered.
static Collector<CharSequence,? ,String> Joining (CharSequence delimiter, CharSequence prefix, CharSequence suffix) returns a Collector, It concatenates the specified prefix and suffix with input elements separated by the specified Collector.
static <T,U,A,R> Collector<T,? ,R> mapping(Function<? super T,? extends U> mapper, Collector<? Super U,A,R> downstream) ADAPTS A Collector type receiving element U to A receiving element T of type by accumulating A mapping function to each input element before applying it.
static Collector<T,? ,Optional> maxBy(Comparator<? Super T> comparator) returns a Collector that generates the maximum element based on the given comparator, described as Optional.
static Collector<T,? ,Optional> minBy(Comparator<? Super T> comparator) returns a Collector that generates the smallest element, described as Optional, based on the given comparator.
static Collector<T,? ,Map<Boolean,List>> partitioningBy(Predicate<? Super T> predicate) returns a Collector that makes predicate of the input elements based on the predicate and organizes them into Map<Boolean, List>.
static <T,D,A> Collector<T,? ,Map<Boolean,D>> partitioningBy(Predicate<? super T> predicate, Collector<? Super T,A,D> downstream) returns A Collector which makes the Predicate on the input elements based on the Predicate, reduces the value of each partition based on the other Collector and organizes it into A Map<Boolean, D>, Its value is the result of downstream reduction.
static Collector<T,? ,Optional> Reducing (BinaryOperator op) returns a Collector that executes the BinaryOperator of its input element at the specified Collector.
static Collector<T,? ,T> Reducing (T identity, BinaryOperator OP) returns to the Collector to perform the next specified BinaryOperator reduction of its input element using the provided identity.
static <T,U> Collector<T,? ,U> reducing(U identity, Function<? super T,? Extends U> mapper, BinaryOperator op) returns a Collector that executes the BinaryOperator of its input element under the specified mapping function and BinaryOperator.
static Collector<T,? ,DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? Super T> mapper) returns a Collector, and the double production mapping function is applied to each input element and returns summary statistics of the resulting value.
static Collector<T,? ,IntSummaryStatistics> summarizingInt(ToIntFunction<? Super T> mapper) returns a Collector, int the production mapping function applied to each input element, and returns summary statistics of the resulting value.
static Collector<T,? ,LongSummaryStatistics> summarizingLong(ToLongFunction<? Super T> mapper) returns a Collector, and long produces the mapping function applied to each input element and returns summary statistics of the resulting value.
static Collector<T,? ,Double> summingDouble(ToDoubleFunction<? Super T> mapper) returns a Collector that produces the sum of the two-valued functions applied to the input element.
static Collector<T,? ,Integer> summingInt(ToIntFunction<? Super T> mapper) returns a Collector that produces the sum of the integer value functions applied to the input element.
static Collector<T,? ,Long> summingLong(ToLongFunction<? Super T> mapper) returns a Collector that produces the sum of the long-valued functions applied to the input element.
static <T,C extends Collection> Collector<T,? ,C> ToCollection (Supplier collectionFactory) returns a Collector that adds the input elements to a new Collection in the order encountered.
static <T,K,U> Collector<T,? ,ConcurrentMap<K,U>> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? Extends U> valueMapper) returns a concurrent Collector that adds elements to a ConcurrentMap with keys and values as a result of applying the provided mapping function to the input elements.
static <T,K,U> Collector<T,? ,ConcurrentMap<K,U>> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? Extends U> valueMapper, BinaryOperator mergeFunction) returns a concurrent Collector that adds elements to a ConcurrentMap, Its keys and values are the result of applying the provided mapping function to the input element.
static <T,K,U,M extends ConcurrentMap<K,U>> Collector<T,? ,M> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? Extends U> valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier) returns a concurrent Collector that adds elements to a ConcurrentMap, Its keys and values are the result of applying the supplied mapping function to the input element.
static Collector<T,? ,List> ToList () returns a Collector that will input the element List to a new List.
static <T,K,U> Collector<T,? ,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? Extends U> valueMapper) returns a Collector that adds elements to a Map whose keys and values are the result of applying the provided mapping function to the input elements.
static <T,K,U> Collector<T,? ,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? Extends U> valueMapper, BinaryOperator mergeFunction) returns a Collector that adds elements to a Map with keys and values as a result of applying the provided mapping function to the input elements.
static <T,K,U,M extends Map<K,U>> Collector<T,? ,M> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? Extends U> valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier) returns a Collector that adds elements to a Map, Its keys and values are the result of applying the supplied mapping function to the input element.
static Collector<T,? ,Set> toSet() Return a Collector that sets the input elements to a new Set.

conclusion

For the new features in Java, except Stream and lamaba expressions, they can help us optimize the code, make our code concise and clear, and avoid tedious and repetitive operations. For those who are interested in this article, they can operate it, and those who do not understand it can leave a message below. Small farmers see the first time to reply to you, thank you, everyone come on!