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)
- Stream can only be operated once
- The Stream method returns a new stream
- 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); }
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); }