JAVA8 Stream

1 Overview of Steam Streaming

Stream has nothing to do with IO stream (InputStream/OutputStream), please temporarily forget the inherent impression of traditional IO stream!
The idea of Stream flow is similar to the “production line” on the factory floor. Stream flow is not a data structure, it does not save data, but processes data
deal with. Stream can be regarded as a process on the pipeline. On the assembly line, a raw material is processed into a product through multiple processes.

Stream API allows us to quickly complete many complex operations, such as filtering, slicing, mapping, searching, deduplication, statistics, matching and reduction.

2 How to get the Stream

First, the default method stream is added to the java.util.Collection interface, which means that all implementations under the Collection interface can obtain the Stream stream through the steam method.

public static void main(String[] args) {<!-- -->
        List<String> list = new ArrayList<>();
        list. stream();
        Set<String> set = new HashSet<>();
        set. stream();
        Vector vector = new Vector();
        vector. stream();
 }

But if the Map interface does not implement the Collection interface, what should we do at this time? At this time, we can obtain the corresponding key value set according to the Map.

public static void main(String[] args) {<!-- -->
        Map<String,Object> map = new HashMap<>();
        Stream<String> stream = map.keySet().stream(); // key
        Stream<Object> stream1 = map.values().stream(); // value
        Stream<Map.Entry<String, Object>> stream2 = map.entrySet().stream(); // entry
}

3 Introduction to common methods of Stream

Common methods of Stream
The operations of the Stream flow model are very rich, and some commonly used APIs are introduced here. These methods can be divided into two types:

Method name Method function Return value type Method type
count count long end
forEach Process one by one void End
filter Filter Stream Function splicing
limit Take the first few Stream Function splicing
skip Skip the first few Stream Function Splicing
map Map Stream Function Splicing
concat combination Stream function splicing

Terminal method: the method whose return value type is no longer Stream type, and chain call is no longer supported. In this section, final methods include count and forEach methods.

Non-terminal method: The return value type is still a method of Stream type, which supports chain calls. Except for the final method, the rest of the methods are non-terminal methods.

Stream Considerations (Important)

  1. Stream can only be operated once
  2. The Stream method returns a new stream
  3. Stream does not call the final method, and the intermediate operations will not be executed

3.1 forEach

Traverse:

public static void main(String[] args) {<!-- -->
        List<String> words = Arrays. asList("Hello", "World");
        words.stream().forEach(System.out::println);
}

3.2 count

The count method in the Stream stream is used to count the number of elements in it:

public static void main(String[] args) {<!-- -->
        List<String> words = Arrays. asList("Hello", "World");
        //for each, count
        System.out.println(words.stream().count());
    }

3.3 filter

The filter method is used to filter data. Return eligible data:

public static void main(String[] args) {<!-- -->
        List<String> words = Arrays.asList("hello", "world", "window", "good", "nice");
        //for each, count
        words.stream().filter(o->o.startsWith("w")).forEach(System.out::println);
    }

3.4 map

If we need to map elements in a stream to another stream, we can use the map method:

public static void main(String[] args) {<!-- -->
        List<String> words = Arrays.asList("hello", "world", "window", "good", "nice");
        //for each, count
        words.stream().map(String::length).forEach(System.out::println);

    }

3.5 sorted

If you need to sort the data, you can use the sorted method:

public static void main(String[] args) {<!-- -->
        List<String> words = Arrays. asList("1", "22", "33", "20", "30");
        //for each, count
        words.stream().map(Integer::parseInt).sorted((n1, n2) -> n2 - n1).forEach(System.out::println);

    }

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture directly Upload (img-ujsDWZEh-1684739478779)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1de44612-5ecf-445a-9365-7bcb0da5aed4/Untitled.png)]

3.6 distinct

If you want to remove duplicate data, you can use the distinct method:

public static void main(String[] args) {<!-- -->
        List<String> words = Arrays.asList("1", "22", "22", "19", "33", "20", "30");
        //for each, count
        words. stream()
                .distinct()
                .map(Integer::parseInt)
                .sorted((n1, n2) -> n2 - n1)
                .forEach(System.out::println);

    }

3.7 Max Min

public static void main(String[] args) {<!-- -->
        List<String> words = Arrays.asList("1", "22", "22", "19", "33", "20", "30");
        //for each, count
        Optional<Integer> max = words. stream(). map(Integer::parseInt)
                .max((o1, o2) -> o1 - o2);
        System.out.println(max.get());

        Optional<Integer> min = words. stream(). map(Integer::parseInt)
                .min((o1, o2) -> o1 - o2);
        System.out.println(min.get());

    }
public static void main(String[] args) {<!-- -->

        List<Person> peoples = Arrays. asList(
                new Person("r1", 12, 180),
                new Person("r2", 13, 180),
                new Person("r3", 14, 180)
        );

        Optional<Person> max = peoples. stream(). max((o1, o2) -> o1. getAge() - o2. getAge());
        System.out.println(max.get());

    }

3.8 reduce

If you need to summarize all the data into one data, you can use the reduce method:

public static void main(String[] args) {<!-- -->

        List<Person> peoples = Arrays. asList(
                new Person("r1", 12, 180),
                new Person("r2", 13, 180),
                new Person("r3", 14, 180)
        );
        // all ages
        Integer reduce = peoples.stream().map(Person::getAge).reduce(0, Integer::sum);
        System.out.println(reduce);

        // maximum value
        Integer maxAge = peoples.stream().map(Person::getAge).reduce(0, Integer::max);
        System.out.println(maxAge);

    }

4 Stream result collection

4.1 In-stream data collection

public static void main(String[] args) {<!-- -->

        List<String> list = Stream.of("aa", "bb", "cc", "aa")
                .collect(Collectors.toList());
        System.out.println(list);
        // Collected into the Set collection
        Set<String> set = Stream.of("aa", "bb", "cc", "aa")
                .collect(Collectors.toSet());
        System.out.println(set);
    }

4.2 Aggregation calculation

public static void main(String[] args) {<!-- -->

        // Get the maximum age
        Optional<Person> maxAge = Stream.of(
                new Person("Zhang San", 18)
                , new Person("Li Si", 22)
                , new Person("Zhang San", 13)
                , new Person("Wang Wu", 15)
                , new Person("Zhang San", 19)
        ).collect(Collectors.maxBy((p1, p2) -> p1.getAge() - p2.getAge()));
        System.out.println("Maximum age: " + maxAge.get());
        // Get the minimum age
        Optional<Person> minAge = Stream.of(
                new Person("Zhang San", 18)
                , new Person("Li Si", 22)
                , new Person("Zhang San", 13)
                , new Person("Wang Wu", 15)
                , new Person("Zhang San", 19)
        ).collect(Collectors.minBy((p1, p2) -> p1.getAge() - p2.getAge()));
        System.out.println("latest age:" + minAge.get());
        // Find the sum of all ages
        Integer sumAge = Stream.of(
                        new Person("Zhang San", 18)
                        , new Person("Li Si", 22)
                        , new Person("Zhang San", 13)
                        , new Person("Wang Wu", 15)
                        , new Person("Zhang San", 19)
                )
                //.collect(Collectors.summingInt(s -> s.getAge()))
                .collect(Collectors.summingInt(Person::getAge))
                ;
        System.out.println("Sum of age: " + sumAge);
        // average age
        Double avgAge = Stream.of(
                new Person("Zhang San", 18)
                , new Person("Li Si", 22)
                , new Person("Zhang San", 13)
                , new Person("Wang Wu", 15)
                , new Person("Zhang San", 19)
        ).collect(Collectors.averagingInt(Person::getAge));
        System.out.println("Average age: " + avgAge);
        // total number
        Long count = Stream.of(
                        new Person("Zhang San", 18)
                        , new Person("Li Si", 22)
                        , new Person("Zhang San", 13)
                        , new Person("Wang Wu", 15)
                        , new Person("Zhang San", 19)
                ).filter(p->p.getAge() > 18)
                .collect(Collectors.counting());
        System.out.println("Number of records that meet the conditions: " + count);
    }

4.3 Group operations on data in the stream

When we use Stream to process data, we can group data according to a certain attribute

public static void main(String[] args) {<!-- -->

        List<Person> peoples = Arrays. asList(
                new Person("r1", 12),
                new Person("r2", 13),
                new Person("r3", 14)
        );

        Map<Integer, List<Person>> collect = peoples. stream(). collect(Collectors. groupingBy(Person::getAge));

        System.out.println(collect);


    }