A preface.

As Java evolves, more and more enterprises are using JDK1.8. JDK1.8 is the most important release since JDK1.5 and includes more than a dozen new features in languages, compilers, libraries, tools, JVMS, and more. This article will focus on Stream.

Stream is the key abstraction for dealing with collections in JDK1.8. Lambda and Stream are some of the highlights of new functional programming in JDK1.8. They specify what you want to do with collections, and can perform very complex operations such as finding, filtering, and mapping data. Manipulating collection data using the Stream API is similar to database queries executed using SQL. Stream provides a high-level abstraction of Java collection operations and expressions in an intuitive manner similar to querying data from a database with SQL statements. The Stream API can greatly improve the productivity of Java programmers, allowing programmers to write efficient, clean, and concise code.

This style treats the collection of elements to be processed as a stream that travels through a pipe and can be processed at the nodes of the pipe, such as filtering, sorting, aggregating, and so on.

The element stream is processed by intermediate operation in the pipe, and finally the result of the previous processing is obtained by terminal operation.

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+
Copy the code

In short, the Stream API provides an efficient and easy-to-use way to process data.


What is Stream

1.Stream is a queue of elements from a data source and supports aggregation operations.

  • Elements are objects of a specific type that form a queue. A Stream in Java does not store elements, but evaluates them on demand.
  • Data source Indicates the source of the flow. These can be collections, arrays, I/O channels, generators, etc.
  • Aggregation operations are similar to SQL statements, such as filter, Map, reduce, find, match, sorted, and so on.

2. Unlike the previous Collection operation, the Stream operation has two basic characteristics:

  • Pipelining: All intermediate operations return the flow object itself. These operations can be cascaded into a pipe, as in fluent style. This allows you to optimize operations, such as delay and short-circuiting.
  • Internal iteration: Previously, collections were iterated explicitly outside the collection using either Iterator or for-each. This is called external iteration. A Stream provides a means of iterating internally through a Visitor pattern.

Features:

  1. Stream is not a data structure and does not hold data.
  2. Stream does not modify the original data source; it stores the manipulated data into another object. (Reservation: After all, the PEEK method can modify elements in the stream.)
  3. Lazy evaluation, in which the flow records the operation during intermediate processing and does not perform the actual calculation until the termination operation is performed.

About the Stream API

1. Stream API classification

A Stream operation can be classified as an intermediate operation or a termination operation. The termination operation returns a result of a particular type, while the intermediate operation returns the Stream itself.

Explanation:

  • Stateless: the processing of an element is not affected by previous elements;

  • Stateful: The operation cannot continue until all elements are retrieved.

  • Non-short-circuit operation: all elements must be processed 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.

2. How to use Stream?

There are three steps to using Stream.

  • Create a Stream

    A data source (e.g., collection, array) that gets a Stream.

  • In the middle of operation

    An intermediate chain of operations that processes data from a data source, such as a collection or array.

  • Termination of operations

    A termination operation that performs an intermediate chain of operations and produces a computed result.

3. Stream intermediate and end operations

  • In the middle of operation

Filter: To filter the Stream. To filter the elements in the Stream, return a Stream that meets the criteria

Map: Transform streams to convert one type of stream to another. (mapToInt, mapToLong, mapToDouble return Stream corresponding to int, long, double)

FlatMap: Simply put, one or more streams merge into a new stream. FlatMapToInt, flatMapToLong, and flatMapToDouble return the corresponding IntStream, LongStream, and DoubleStream streams.

Distinct: returns a Stream with a duplicate.

Sorted: Returns a sorted Stream.

Peek: Mainly used to view the data status of elements in the stream.

Limit: Returns a Stream consisting of the first n elements. Short circuit operation

Skip: Returns the Stream after the NTH element.

  • End of operation

ForEach: Loops over data in a Stream.

ToArray: Returns the array object corresponding to the element in the stream.

Reduce: the aggregation operation is used for statistics.

Collect: Encapsulates target data.

Min, Max, count: aggregate operation, minimum value, maximum value, total quantity.

AnyMatch: Short-circuit operation that returns true if one condition is met.

AllMatch: Returns true if all data matches the criteria.

NoneMatch: Returns true if all data does not qualify.

FindFirst: Short-circuit operation to get the first element.

FindAny: Short-circuit operation to obtain any element.

ForEachOrdered: Dark elements are looped in order.


How to obtain a Stream

In Java 8, the collection interface has two methods to generate streams:

  • Stream () − Creates a serial stream for the collection.
  • ParallelStream () − Creates parallel streams for collections.

1. Common creation of several collection streams

/** * stream, get various collections of streams */
@Test
public void testCollectionStream(a){
    / / the List collection
    List<String> stringList = new ArrayList<>();
    / / Set collection
    Set<String> stringSet = new HashSet<>();
    / / Map collections
    Map<String,Object> stringObjectMap = new HashMap<>();
    / / array
    String[] stringArray = {"Jonathan"."Bill"."Fifty"."Fifty"."Zhao."};// Get the stream from list
    Stream<String> streamList = stringList.stream();
    // Get a stream from set
    Stream<String> streamSet = stringSet.stream();
    // Get the stream from map
    Stream<String> streamMap = stringObjectMap.keySet().stream();
    // Get a stream from array
    Stream<String> streamArray1 = Stream.of(stringArray);
}
Copy the code

2. Several common ways to construct a flow

@Test
public void testCollectionStream(a){
   // 1. Individual values
  Stream stream = Stream.of("a"."b"."c");
  
  // 2. Arrays
  String[] strArray = new String[]{"a"."b"."c"};
  stream = Stream.of(strArray);
  stream = Arrays.stream(strArray);
  
  // 3. Collections
  List<String> list = Arrays.asList(strArray);
  stream = list.stream();
  
}
Copy the code

How Stream is used in code

The common operations on Stream are divided into two categories: intermediate operations and termination operations.

1. Intermediate operations for streams

1.1 Filtering

  • Filter: Filters certain elements in the stream
       /** * filter method, which returns the value */ matching the filter criteria
        @Test
        public void testFilter(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.stream().filter(e -> e.contains("Zhang")).forEach(System.out::println);
        }
    Copy the code

  • Filter Multiple filter criteria
   /** * list set stream */
  @Test
  public void testStreamList(a) {
      List<String> list = new ArrayList<>();
      list.add("Jonathan");
      list.add("Bill");
      list.add("Fifty");
      list.add("Seven sun");
      list.add("Zhao.");
      list.stream().filter(e -> e.startsWith("Zhang")) // Filter all zhangs
              .filter(e -> e.length() == 3) // Filter all names with 3 characters
              .forEach(System.out::println); Out ::println indicates that System.out calls the println printing method
  }
Copy the code
  • Limit (n) : Gets the first n elements

     /** * limit returns a Stream consisting of the first n element values. * /
        @Test
        public void testLimit(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            list.stream().limit(3).forEach(System.out::println); // take the first three
        }
    Copy the code
  • Skip (n) : Skip n elements, together with limit(n) can achieve paging

     /** * skip method, which skips intermediate flow operations for the first n elements and returns the remaining values. * /
        @Test
        public void testSkip(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            //list.stream().skip(3).forEach(System.out::println); // Skip the first three
            list.stream().skip(3).limit(2).forEach(System.out::println); //skip+limit
        }
    Copy the code
  • Distinct: Removes duplicate elements by hashCode() and equals() of elements in the stream

     /** * distinct, return Stream */
        @Test
        public void testDistinct(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Bill");
            list.add("Fifty");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            list.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
        }
    Copy the code

1.2 the sorting

  • Sorted () : Sort naturally. Elements in a stream need to implement the Comparable interface

     Sorted: returns a sorted Stream */
        @Test
        public void testSorted(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Bill");
            list.add("Fifty");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            list.stream().distinct().sorted().collect(Collectors.toList()).forEach(System.out::println);
        }
    Copy the code
  • Sorted (Comparator com) : Custom sort, custom Comparator sorter

1.3 mapping

  • Map: Takes as an argument a function that is applied to each element and maps it to a new element.
/** * traverses the map collection, intercepting the value at the beginning of substring(2) */
   @Test
   public void testMap(a) {
       List<String> list = new ArrayList<>();
       list.add("Jonathan");
       list.add("Bill");
       list.add("Fifty");
       list.add("Seven sun");
       list.add("Zhao.");
       list.add("Two pockmarks of Wang.");
       Stream<String> stream = list.stream().map(e -> e.substring(2));
       stream.forEach(System.out::println);
   }
Copy the code
  • ForEach: The forEach stream traverses the collection

      /**
         * forEach, ForEach流式遍历list集合
         */
        @Test
        public void testForEach(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.stream().forEach(System.out::println);
        }
    Copy the code

2. Terminate the flow

2.1 Matching and aggregation operations

  • AllMatch: Accepts a Predicate function that returns true only if every element in the stream matches the Predicate, and false otherwise

     /** * allMatch: Receives a Predicate function that returns true only if each element in the stream matches the Predicate, and false */ otherwise
        @Test
        public void testAllMatch(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Bill");
            list.add("Fifty");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            boolean b = list.stream()
                    .allMatch(e -> list.size() > 8);
            System.out.println("b = " + b);
        }
    Copy the code
  • NoneMatch: Receives a Predicate function that returns true only if each element in the stream does not match the Predicate, and false otherwise

        /** * noneMatch: Receives a Predicate function that returns true only if each element in the stream does not match the Predicate, or false */ otherwise
        @Test
        public void testNoneMatch(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Bill");
            list.add("Fifty");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            boolean b = list.stream().noneMatch(e->e.equals("Zhang"));
            System.out.println("b = " + b);
        }
    Copy the code
  • AnyMatch: Accepts a Predicate function that returns true as long as one element of the stream satisfies the Predicate, and false otherwise

    /** * anyMatch: Receives a Predicate function that returns true as long as one element of the stream satisfies the Predicate, or false */ otherwise
        @Test
        public void testAnyMatch(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Bill");
            list.add("Fifty");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            boolean b = list.stream().anyMatch(e -> e.equals("Two pockmarks of Wang."));
            System.out.println("b = " + b);
        }
    Copy the code
  • FindFirst: Returns the first element in the stream

     /** * findFirst: returns the first element in the stream */
        @Test
        public void testFindFirsth(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Bill");
            list.add("Fifty");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            Optional<String> first = list.stream().findFirst();
            System.out.println("first = " + first.get());
        }
    Copy the code
  • FindAny: Returns any element in the stream

        /** * findAny: Returns the first element in the stream */
        @Test
        public void testFindAny(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Bill");
            list.add("Fifty");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            Optional<String> any = list.stream().findAny();
            System.out.println("any = " + any.get());
        }
    Copy the code
  • Count: Returns the total number of elements in the stream

     /** * count, get the length of the List */
        @Test
        public void testCount(a) {
            List<String> list = new ArrayList<>();
            list.add("Jonathan");
            list.add("Bill");
            list.add("Fifty");
            list.add("Seven sun");
            list.add("Zhao.");
            list.add("Two pockmarks of Wang.");
            long count = list.stream().count();
            System.out.println("count = " + count);
            int size = list.size();
            System.out.println("size = " + size);
        }
    Copy the code
  • Max: Returns the maximum value of elements in the stream

    /** * Max: returns the maximum number of elements in the stream */
        @Test
        public void testMax(a) {
            List<Integer> list = new ArrayList<>();
            list.add(11);
            list.add(22);
            list.add(33);
            list.add(44);
            list.add(55);
            list.add(66);
            list.add(77);
            list.add(88);
            Integer integer = list.stream().max(Integer::compareTo).get();
            System.out.println("integer = " + integer);
        }
    Copy the code
  • Min: Returns the minimum value of the element in the stream

    /** * min: returns the minimum element in the stream */
    @Test
    public void testMin(a) {
        List<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(22);
        list.add(33);
        list.add(44);
        list.add(55);
        list.add(66);
        list.add(77);
        list.add(88);
        Integer integer = list.stream().min(Integer::compareTo).get();
        System.out.println("integer = " + integer);
        list.stream().limit(1).limit(2).distinct().skip(3).filter(f -> f.equals(55)).forEach(System.out::println);
    }
    Copy the code

2.2 Collector Tool Library: Collectors

  • Collectors

    Student s1 = new Student("aa".10.1);
    Student s2 = new Student("bb".20.2);
    Student s3 = new Student("cc".10.3);
    List<Student> list = Arrays.asList(s1, s2, s3);
      
    / / put into the list
    List<Integer> ageList = list.stream().map(Student::getAge).collect(Collectors.toList()); / / [10, 20, 10]
      
    / / into the set
    Set<Integer> ageSet = list.stream().map(Student::getAge).collect(Collectors.toSet()); / / [20, 10]
      
    // Convert to map. Note: The keys must be different; otherwise, an error will be reported
    Map<String, Integer> studentMap = list.stream().collect(Collectors.toMap(Student::getName, Student::getAge)); // {cc=10, bb=20, aa=10}
      
    // String delimiter connection
    String joinName = list.stream().map(Student::getName).collect(Collectors.joining(","."(".")")); // (aa,bb,cc)
      
    // Aggregate operations
    //1
    Long count = list.stream().collect(Collectors.counting()); / / 3
    //2. Maximum age (same with minBy)
    Integer maxAge = list.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get(); / / 20
    //3. Age of everyone
    Integer sumAge = list.stream().collect(Collectors.summingInt(Student::getAge)); / / 40
    //4. Average age
    Double averageAge = list.stream().collect(Collectors.averagingDouble(Student::getAge)); / / 13.333333333333334
    // Bring all of the above methods
    DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(Student::getAge));
    System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
      
    / / group
    Map<Integer, List<Student>> ageMap = list.stream().collect(Collectors.groupingBy(Student::getAge));
    // Multiple groups, first by type and then by age
    Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getType, Collectors.groupingBy(Student::getAge)));
      
    / / 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<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));
      
    / / code
    Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get(); / / 40
    Copy the code

Stream operation code

In order to facilitate friends to see this blog, learning more easily, here posted the source code, friends to learn is posted to IDEA to run the Stream filter screening results, so as to be more familiar with the Stream operation.

package com.java8.example.chapter3;

import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/ * * *@desc: Stream The Stream operation *@author: cao_wencao
 * @date: in the 2020-09-17 s and the * /
public class TestStreamList {

    /** * list set stream */
    @Test
    public void testStreamList(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.stream().filter(e -> e.startsWith("Zhang")) // Filter all zhangs
                .filter(e -> e.length() == 3) // Filter all names with 3 characters
                .forEach(System.out::println); Out ::println indicates that System.out calls the println printing method
    }

    /** * stream, get various collections of streams */
    @Test
    public void testCollectionStream(a) {
        List<String> stringList = new ArrayList<>();
        Set<String> stringSet = new HashSet<>();
        Map<String, Object> stringObjectMap = new HashMap<>();
        String[] stringArray = {"Jonathan"."Bill"."Fifty"."Fifty"."Zhao."};// Get the stream from list
        Stream<String> streamList = stringList.stream();
        // Get a stream from set
        Stream<String> streamSet = stringSet.stream();
        // Get the stream from map
        Stream<String> streamMap = stringObjectMap.keySet().stream();
        // Get a stream from array
        Stream<String> streamArray1 = Stream.of(stringArray);

    }

    /**
     * forEach, ForEach流式遍历list集合
     */
    @Test
    public void testForEach(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.stream().forEach(System.out::println);
    }

    /** * filter method, which returns the value */ matching the filter criteria
    @Test
    public void testFilter(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.stream().filter(e -> e.contains("Zhang")).forEach(System.out::println);
    }

    /** * traverses the map collection, intercepting the value at the beginning of substring(2) */
    @Test
    public void testMap(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        Stream<String> stream = list.stream().map(e -> e.substring(2));
        stream.forEach(System.out::println);
    }

    /** * count, get the length of the List */
    @Test
    public void testCount(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        long count = list.stream().count();
        System.out.println("count = " + count);
        int size = list.size();
        System.out.println("size = " + size);
    }

    /** * limit returns a Stream consisting of the first n element values. * /
    @Test
    public void testLimit(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        list.stream().limit(3).forEach(System.out::println); // take the first three
    }

    /** * skip method, which skips intermediate flow operations for the first n elements and returns the remaining values. * /
    @Test
    public void testSkip(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        //list.stream().skip(3).forEach(System.out::println); // Skip the first three
        list.stream().skip(3).limit(2).forEach(System.out::println); //skip+limit
    }

    /** * collect */
    @Test
    public void testCollect(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        List<String> collect = list.stream().skip(3).limit(2).collect(Collectors.toList());
        collect.forEach(System.out::println);
    }

    /** * distinct, return Stream */
    @Test
    public void testDistinct(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Bill");
        list.add("Fifty");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        list.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
    }

    Sorted: returns a sorted Stream */
    @Test
    public void testSorted(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Bill");
        list.add("Fifty");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        list.stream().distinct().sorted().collect(Collectors.toList()).forEach(System.out::println);
    }

    /** * anyMatch: Receives a Predicate function that returns true as long as one element of the stream satisfies the Predicate, or false */ otherwise
    @Test
    public void testAnyMatch(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Bill");
        list.add("Fifty");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        boolean b = list.stream().anyMatch(e -> e.equals("Two pockmarks of Wang."));
        System.out.println("b = " + b);
    }

    /** * noneMatch: Receives a Predicate function that returns true only if each element in the stream does not match the Predicate, or false */ otherwise
    @Test
    public void testNoneMatch(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Bill");
        list.add("Fifty");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        boolean b = list.stream().noneMatch(e->e.equals("Zhang"));
        System.out.println("b = " + b);
    }

    /** * allMatch: Receives a Predicate function that returns true only if each element in the stream matches the Predicate, and false */ otherwise
    @Test
    public void testAllMatch(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Bill");
        list.add("Fifty");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        boolean b = list.stream()
                .allMatch(e -> list.size() > 8);
        System.out.println("b = " + b);
    }

    /** * findFirst: returns the first element in the stream */
    @Test
    public void testFindFirsth(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Bill");
        list.add("Fifty");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        Optional<String> first = list.stream().findFirst();
        System.out.println("first = " + first.get());
    }


    /** * findAny: Returns the first element in the stream */
    @Test
    public void testFindAny(a) {
        List<String> list = new ArrayList<>();
        list.add("Jonathan");
        list.add("Bill");
        list.add("Bill");
        list.add("Fifty");
        list.add("Fifty");
        list.add("Seven sun");
        list.add("Zhao.");
        list.add("Two pockmarks of Wang.");
        Optional<String> any = list.stream().findAny();
        System.out.println("any = " + any.get());
    }

    /** * Max: returns the maximum number of elements in the stream */
    @Test
    public void testMax(a) {
        List<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(22);
        list.add(33);
        list.add(44);
        list.add(55);
        list.add(66);
        list.add(77);
        list.add(88);
        Integer integer = list.stream().max(Integer::compareTo).get();
        System.out.println("integer = " + integer);
    }

    /** * min: returns the minimum element in the stream */
    @Test
    public void testMin(a) {
        List<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(22);
        list.add(33);
        list.add(44);
        list.add(55);
        list.add(66);
        list.add(77);
        list.add(88);
        Integer integer = list.stream().min(Integer::compareTo).get();
        System.out.println("integer = " + integer);
        list.stream().limit(1).limit(2).distinct().skip(3).filter(f -> f.equals(55)).forEach(System.out::println); }}Copy the code

conclusion

This article is intended as a simple introduction to the new features in JDK1.8. For more information, see the following articles in the JDK1.8 series.

Long press the qr code below, follow the public account “Thinking Cao”, ON the way to Java architecture, I want to move forward with you and make progress together!