Stream stream
experience
- Requirements: complete the creation and traversal of the collection according to the following requirements
- Create a collection to store the string elements
- Store all elements in the collection that begin with "Zhang" into a new collection
- Store the 3-length elements in the set beginning with "Zhang" into a new set
- Traverse the previous step to get the set
import java.util.ArrayList; public class Demo { public static void main(String[] args) { //Mode 1 System.out.println("-------Mode 1---------"); ArrayList<String> array = new ArrayList<>(); ArrayList<String> zhanglist = new ArrayList<>(); ArrayList<String> threelist = new ArrayList<>(); array.add("Zhang Sanfeng"); array.add("Jia Baoyu"); array.add("Lin Daiyu"); array.add("Yang Guo"); array.add("Guo Jing"); array.add("Zhang Min"); array.add("zhang wuji"); for (String i : array) { if (i.startsWith("Zhang")) { zhanglist.add(i); } } for (String i : zhanglist) { if (i.length() == 3) { threelist.add(i); } } for (String i : threelist) { System.out.println(i); } System.out.println("--------Mode 2----------"); //Mode 2: //Stream stream System.out.println("-------Lambda expression-----"); array.stream().filter(s -> s.startsWith("Zhang")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s)); System.out.println("--------Method reference--------"); array.stream().filter(s -> s.startsWith("Zhang")).filter(s -> s.length() == 3).forEach(System.out::println); } }
Directly reading the literal sense of the code can perfectly display the semantics of irrelevant logic: generating flow, filtering surname Zhang, filtering length 3, printing one by one
Stream stream brings real functional programming style into java
How to generate Stream
Use of Stream stream
- Generative flow
- Generate streams from data sources (collections, arrays, etc.)
- list.stream()
- Intermediate operation
- One flow can be followed by zero or more intermediate operations. The main purpose is to open the flow, make some degree of data filtering / mapping, and then return a new flow to the next operation
- filter()
- Summary operation
- A stream can only have one end operation. When this operation is performed, the stream will be used with "light" and can no longer be operated. So this must be the last operation of the flow
- forEach()
How to generate Stream
Common ways to generate Stream
- A Collection of Collection systems can generate streams using the default method stream()
- default Stream stream()
- The set indirect generating flow of Map system
- Arrays can generate streams through the static method of(T...values) of the Stream interface
import java.util.*; import java.util.stream.Stream; public class Demo { public static void main(String[] args) { //A Collection of Collection systems can generate streams using the default method stream() List<String> list = new ArrayList<>(); Stream<String> listStream = list.stream(); Set<String> set = new TreeSet<>(); Stream<String> SetStream = set.stream(); //The set indirect generating flow of Map system Map<String, Integer> map = new HashMap<>(); Stream<String> KeyStream = map.keySet().stream(); Stream<Integer> valuesStream = map.values().stream(); Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream(); //Arrays can generate streams through the static method of(T...values) of the Stream interface String[] str = {"HELLO", "WORLD", "JAVA"}; Stream<String> strStream = Stream.of(str); Stream<String> strStream2 = Stream.of("hello", "world", "java"); Stream<Integer> intStream = Stream.of(1, 2, 3); } }
Common intermediate operation methods of Stream stream
- Stream filter(Predicate predicate): used to filter the data in the stream
- Method Boolean test (t t t) in Predicate interface: judge the given parameter and return a Boolean value
import java.util.ArrayList; public class Demo { public static void main(String[] args) { ArrayList<String> array = new ArrayList<>(); array.add("Zhang Sanfeng"); array.add("Jia Baoyu"); array.add("Lin Daiyu"); array.add("Yang Guo"); array.add("Guo Jing"); array.add("Zhang Min"); array.add("zhang wuji"); //Output the elements in the list collection that begin with sheets in the console array.stream().filter(s -> s.startsWith("Zhang")).forEach(System.out::println); System.out.println("-----------"); //Output the element with length of 3 in the list collection in the console array.stream().filter(s -> s.length() == 3).forEach(System.out::println); System.out.println("-----------"); //Start the list collection with a piece, and the element with length of 3 is output too array.stream().filter(s -> s.startsWith("Zhang")).filter(s -> s.length() == 3).forEach(System.out::println); } }
- Stream limit(long maxSize): returns the stream composed of the elements in the stream, and intercepts the data of the parameters specified before
- Stream skip(long n): skip the data with the specified number of parameters and return the stream composed of the remaining elements of the stream
import java.util.ArrayList; public class Demo2 { public static void main(String[] args) { ArrayList<String> array = new ArrayList<>(); array.add("Zhang Sanfeng"); array.add("Jia Baoyu"); array.add("Lin Daiyu"); array.add("Yang Guo"); array.add("Guo Jing"); array.add("Zhang Min"); array.add("zhang wuji"); //Take the first three data to output in the console array.stream().limit(3).forEach(System.out::println); System.out.println("-----------------"); //Skip 3 elements and output the rest in the console array.stream().skip(3).forEach(System.out::println); System.out.println("-----------------"); //Skip two elements and output the first two of the remaining elements in the console array.stream().skip(2).limit(2).forEach(System.out::println); } }
- static Stream concat(Stream a,Stream b): merge two streams a and B into one stream
- Stream distinct(): returns a stream composed of different elements of the stream (based on Objectequals(Object))
import java.util.ArrayList; import java.util.stream.Stream; public class Demo3 { public static void main(String[] args) { ArrayList<String> array = new ArrayList<>(); array.add("Zhang Sanfeng"); array.add("Jia Baoyu"); array.add("Lin Daiyu"); array.add("Yang Guo"); array.add("Guo Jing"); array.add("Zhang Min"); array.add("zhang wuji"); //Take the first four data to form a flow Stream<String> s1 = array.stream().limit(4); //Skip 2 data to form a stream Stream<String> s2 = array.stream().skip(2); //Merge the two streams and output the results // Stream.concat(s1,s2).forEach(System.out::println); //Merge the two streams and output the result. The character elements are not repeated Stream.concat(s1,s2).distinct().forEach(System.out::println); } }
- Stream sorted(): returns the stream composed of the elements of this stream, sorted according to the natural order
- Streamsorted(Comparator comparator): returns the flow composed of the elements of the flow, and sorts according to the provided Comparator
import java.util.ArrayList; public class Demo4 { public static void main(String[] args) { ArrayList<String> arrry = new ArrayList<String>(); arrry.add("dd"); arrry.add("cccc"); arrry.add("aa"); arrry.add("bbb"); //Sort alphabetically and output arrry.stream().sorted().forEach(System.out::println); System.out.println("------------"); //Output the data in the descending order of the console according to the string length // arrry.stream().sorted((s1,s2) -> s2.length() - s1.length()).forEach(System.out::println); //If the length is equal, arrange in natural order arrry.stream().sorted((s1, s2) -> { int num = s2.length() - s1.length(); int num2 = num == 0 ? s1.compareTo(s2) : num; return num2; }).forEach(System.out::println); } }
- Stream map(Function mapper): returns a stream consisting of the results of the elements to which a given function applies
- Method R apply (t t t) in Function interface
- IntStream mapToInt(ToIntFunction mapper): returns an IntStream containing the result of applying the Godin function to the element of the stream
- IntStream: indicates the original int stream
- Method int applyAsInt(T value) in the ToIntFunction interface
import java.util.ArrayList; public class Demo5 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("10"); list.add("20"); list.add("30"); list.add("40"); list.add("50"); //Output in the console after converting string data in the collection to integers // list.stream().map(Integer::parseInt).forEach(System.out::println); // list.stream().mapToInt(Integer::parseInt).forEach(System.out::println); //int sum() returns the sum of the elements in this stream int sum = list.stream().mapToInt(Integer::parseInt).sum(); System.out.println(sum); } }
Common termination methods of Stream
- Void for each (consumer action): performs an action on an element of this flow
- Method void accept (t t t) in the Consumer interface: do this for the given parameter
- long count(): returns the number of elements in this stream
import java.util.ArrayList; public class Demo { public static void main(String[] args) { ArrayList<String> array = new ArrayList<>(); array.add("Zhang Sanfeng"); array.add("Jia Baoyu"); array.add("Lin Daiyu"); array.add("Yang Guo"); array.add("Guo Jing"); array.add("Zhang Min"); array.add("zhang wuji"); //Output the elements in the collection in the console array.stream().forEach(System.out::println); System.out.println("----------------"); //There are several elements in the statistics collection that start with Zhang, and the statistics results are output in the console long c = array.stream().filter(s -> s.startsWith("Zhang")).count(); System.out.println(c); } }
practice:
There are two ArrayList sets, which store the names of six actors and six actresses respectively. The following operations are required
- The actor needs only the first three names
- Actresses only need Zhang's surname and don't want to be the first
- Combine the filtered actor and actress names
- Take the element after the previous operation as the parameter of the construction method to create the actor object and traverse the data
- Actor class contains a member traversal, a construction method with parameters, and a get/set method corresponding to member variables
import java.util.ArrayList; import java.util.stream.Stream; public class Demo { public static void main(String[] args) { ArrayList<String> Acto = new ArrayList<>(); ArrayList<String> Actress = new ArrayList<>(); Acto.add("Jackie Chan"); Acto.add("Qiao Zhenyu"); Acto.add("Lau Andy"); Acto.add("Hu Ge"); Acto.add("Zhou Xingchi"); Acto.add("Wu Mengda"); Actress.add("Jingtian"); Actress.add("Zhang Tianai"); Actress.add("Jiang Shuying"); Actress.add("Han Xue"); Actress.add("Zhang Junning"); Actress.add("Zhang Meng"); System.out.println("-----Mode 1-----"); //*An actor needs only the first three names Stream<String> acto = Acto.stream().filter(s -> s.length() == 3).limit(3); //*Actresses only need Zhang's surname and don't want to be the first Stream<String> actress = Actress.stream().filter(s -> s.startsWith("Zhang")).skip(1); //*Combine the filtered actor and actress names Stream<String> actor = Stream.concat(acto, actress); actor.map(Actor::new).forEach(p -> System.out.println(p.getName())); System.out.println("-----Mode 2 (merger)-----"); Stream.concat(Acto.stream().filter(s -> s.length() == 3).limit(3),Actress.stream().filter(s -> s.startsWith("Zhang")).skip(1)).map(Actor::new).forEach(p -> System.out.println(p.getName())); } }
Collection operation of Stream stream
After using the flow method to operate the data, I want to collect the data in the flow into the collection. What should I do
- R collect(Collector collector)
- But the parameter of this collection method is a Collector interface
Tool class Collectors provide specific collection methods
- public static Collector toList(): collect elements into the List collection
- public static Collector toSet(): collect elements into Set collection
- Public static collector to Map (function keymapper, function valuemapper): collect elements into the Map collection
import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; public class Demo { public static void main(String[] args) { ArrayList<String> Acto = new ArrayList<>(); Acto.add("Jackie Chan"); Acto.add("Qiao Zhenyu"); Acto.add("Lau Andy"); Acto.add("Hu Ge"); Acto.add("Zhou Xingchi"); Acto.add("Wu Mengda"); //Get a stream named 3 words Stream<String> acto = Acto.stream().filter(s -> s.length() == 3); //Use Stream stream to collect the completed data into List collection and traverse List<String> list = acto.collect(Collectors.toList()); for (String i : list) { System.out.println(i); } System.out.println("--------------------"); Set<Integer> set = new HashSet<Integer>(); set.add(10); set.add(20); set.add(25); set.add(30); set.add(33); set.add(35); //Get a flow greater than 25 Stream<Integer> age = set.stream().filter(s -> s > 25); //Collect the data after using Stream stream operation into Set collection and traverse Set<Integer> a = age.collect(Collectors.toSet()); for (Integer i : a) { System.out.println(i); } System.out.println("---------------------------"); //Define an array of strings, each composed of name and age String[] strArray = {"Qiao Zhenyu,30", "Lau Andy,33", "Zhou Xingchi,25", "Wu Mengda,35"}; //Get a stream with age data greater than 28 in the string Stream<String> stream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28); //Collect the data after the Stream operation into the Map set and traverse it, with the name in the string as the key and the age as the value Map<String, Integer> map = stream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1]))); Set<String> keys = map.keySet(); for (String key : keys){ Integer value = map.get(key); System.out.println(key+","+value); } } }