Stream 流
體驗
- 需求:按下面得要求完成集合的創建和遍歷
- 創建一個集合,存盤多啊哥字串元素
- 把集合中所有以"張"開頭的元素存盤到一個新的集合
- 把"張"開頭的集合中的長度為3的元素存盤到一個新的集合
- 遍歷上一步得到集合
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
//方式一
System.out.println("-------方式一---------");
ArrayList<String> array = new ArrayList<>();
ArrayList<String> zhanglist = new ArrayList<>();
ArrayList<String> threelist = new ArrayList<>();
array.add("張三豐");
array.add("賈寶玉");
array.add("林黛玉");
array.add("楊過");
array.add("郭靖");
array.add("張敏");
array.add("張無忌");
for (String i : array) {
if (i.startsWith("張")) {
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("--------方式二----------");
//方式二:
//Stream流
System.out.println("-------Lambda運算式-----");
array.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
System.out.println("--------方法參考--------");
array.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(System.out::println);
}
}
直接閱讀代碼的字面意識即可完美展示無關邏輯方式的語意:生成流、過濾姓張、過濾長度為3、逐一列印
Stream流把真正的函式式編程風格引入到了java中
Stream流的生成方式
Stream流的使用
- 生成流
- 通過資料源(集合,陣列等)生成流
- list.stream()
- 中間操作
- 一個流后面可以跟隨零個或多個中間操作,其目的主要是打開流,做出某種程度的資料過濾/映射,然后回傳一個新的流,交給下一個操作使用
- filter()
- 總結操作
- 一個流只能有一個終結操作,當這個操作執行后,流就被使用"光"了,無法再被操作,所以這必定是流的最后一個操作
- forEach()
Stream流的生成方式
Stream流的常見生成方式
- Collection體系的集合可以使用默認的方法stream()生成流
- default Stream
stream()
- default Stream
- Map體系的集合間接的生成流
- 陣列可以通過Stream介面的靜態方法of(T...values)生成流
import java.util.*;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
//Collection體系的集合可以使用默認的方法stream()生成流
List<String> list = new ArrayList<>();
Stream<String> listStream = list.stream();
Set<String> set = new TreeSet<>();
Stream<String> SetStream = set.stream();
//Map體系的集合間接的生成流
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();
//陣列可以通過Stream介面的靜態方法of(T...values)生成流
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);
}
}
Stream流常見中間操作方法
- Stream
filter(Predicate predicate):用于流中的資料進行過濾 - Predicate介面中的方法 boolean test(T t):對給定的引數進行判斷,回傳一個布林值
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<>();
array.add("張三豐");
array.add("賈寶玉");
array.add("林黛玉");
array.add("楊過");
array.add("郭靖");
array.add("張敏");
array.add("張無忌");
//把list集合中以張開頭的元素在控制臺輸出
array.stream().filter(s -> s.startsWith("張")).forEach(System.out::println);
System.out.println("-----------");
//把list集合中長度為3的元素在控制臺輸出
array.stream().filter(s -> s.length() == 3).forEach(System.out::println);
System.out.println("-----------");
//把list集合中以張開頭,長度為3的元素在控制太輸出
array.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(System.out::println);
}
}
- Stream
limit(long maxSize):回傳流中的元素組成的流,截取前指定引數的資料 - Stream
skip(long n):跳過指定引數個數的資料,回傳由該流剩余元素組成的流
import java.util.ArrayList;
public class Demo2 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<>();
array.add("張三豐");
array.add("賈寶玉");
array.add("林黛玉");
array.add("楊過");
array.add("郭靖");
array.add("張敏");
array.add("張無忌");
//取前3個資料在控制臺輸出
array.stream().limit(3).forEach(System.out::println);
System.out.println("-----------------");
//跳過3個元素,把剩下的元素在控制臺輸出
array.stream().skip(3).forEach(System.out::println);
System.out.println("-----------------");
//跳過兩個元素,把剩下的元素中前2個在控制臺輸出
array.stream().skip(2).limit(2).forEach(System.out::println);
}
}
- static
Stream concat(Stream a,Stream b):合并a和b兩個流為一個流 - Stream
distinct():回傳由該流的不同元素(根據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("張三豐");
array.add("賈寶玉");
array.add("林黛玉");
array.add("楊過");
array.add("郭靖");
array.add("張敏");
array.add("張無忌");
//取前4個資料組成一個流
Stream<String> s1 = array.stream().limit(4);
//跳過2個資料組成一個流
Stream<String> s2 = array.stream().skip(2);
//合并得到的兩個流,并輸出結果
// Stream.concat(s1,s2).forEach(System.out::println);
//合并得到的兩個流,并輸出結果,要求字符元素不重復
Stream.concat(s1,s2).distinct().forEach(System.out::println);
}
}
- Stream
sorted():回傳由此流的元素組成的流,根據自然順序排序 - Stream
sorted(Comparator comparator):回傳由該流的元素組成的流,根據提供的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");
//按照字母順序排序并輸出
arrry.stream().sorted().forEach(System.out::println);
System.out.println("------------");
//按照字串長度把資料輸出在控制臺 降序
// arrry.stream().sorted((s1,s2) -> s2.length() - s1.length()).forEach(System.out::println);
//若長度相等按自然順序排
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):回傳由給定函式應用于此流的元素的結果組成的流 - Function介面中的方法 R apply(T t)
- IntStream mapToInt(ToIntFunction mapper):回傳一個IntStream其中包含將戈丁函式應用于此流的元素的結果
- IntStream:表示原始int流
- ToIntFunction介面中的方法 int applyAsInt(T value)
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");
//將集合中的字串資料轉換為整數之后在控制臺輸出
// list.stream().map(Integer::parseInt).forEach(System.out::println);
// list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
//int sum()回傳此流中元素的總和
int sum = list.stream().mapToInt(Integer::parseInt).sum();
System.out.println(sum);
}
}
Stream流的常見終結操作方法
- void forEach(Consumer action):對此流的元素執行操作
- Consumer介面中的方法 void accept(T t):對給定的引數執行此操作
- long count():回傳此流中的元素數
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<>();
array.add("張三豐");
array.add("賈寶玉");
array.add("林黛玉");
array.add("楊過");
array.add("郭靖");
array.add("張敏");
array.add("張無忌");
//把集合中的元素在控制臺輸出
array.stream().forEach(System.out::println);
System.out.println("----------------");
//統計集合中有幾個以張開頭的元素,并把統計結果在控制臺輸出
long c = array.stream().filter(s -> s.startsWith("張")).count();
System.out.println(c);
}
}
練習:
現有兩個ArrayList集合,分別存盤6名男演員名稱和6名女演員名稱,需求完成如下操作
- 男演員只要名字為3個字的前三人
- 女演員只要姓張的,并且不要第一個
- 把過濾后的男演員和女演員姓名合并到一起
- 把上一步操作后的元素作為構造方法的引數創建演員物件,遍歷資料
- 演員類Actor,里面有一個成員遍歷,一個帶參構造方法,以及成員變數對應的get/set方法
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("成龍");
Acto.add("喬振宇");
Acto.add("劉德華");
Acto.add("胡歌");
Acto.add("周星馳");
Acto.add("吳孟達");
Actress.add("景甜");
Actress.add("張天愛");
Actress.add("江疏影");
Actress.add("韓雪");
Actress.add("張鈞甯");
Actress.add("張萌");
System.out.println("-----方式一-----");
//* 男演員只要名字為3個字的前三人
Stream<String> acto = Acto.stream().filter(s -> s.length() == 3).limit(3);
//* 女演員只要姓張的,并且不要第一個
Stream<String> actress = Actress.stream().filter(s -> s.startsWith("張")).skip(1);
//* 把過濾后的男演員和女演員姓名合并到一起
Stream<String> actor = Stream.concat(acto, actress);
actor.map(Actor::new).forEach(p -> System.out.println(p.getName()));
System.out.println("-----方式二(合并)-----");
Stream.concat(Acto.stream().filter(s -> s.length() == 3).limit(3),Actress.stream().filter(s -> s.startsWith("張")).skip(1)).map(Actor::new).forEach(p -> System.out.println(p.getName()));
}
}
Stream流的收集操作
對資料使用流的方式操作完畢后,我想把流中的資料收集到集合中,該怎么辦呢
- R collect(Collector collector)
- 但是這個收集方法的引數是一個Collector介面
工具類Collectors提供了具體的收集方式
- public static
Collector toList():把元素收集到List集合中 - public static
Collector toSet():把元素收集到Set集合中 - public static Collector toMap(Function KeyMapper,Function valueMapper):把元素收集到Map集合中
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("成龍");
Acto.add("喬振宇");
Acto.add("劉德華");
Acto.add("胡歌");
Acto.add("周星馳");
Acto.add("吳孟達");
//得到名字為3個字的流
Stream<String> acto = Acto.stream().filter(s -> s.length() == 3);
//使用Stream流操作完畢的資料收集到List集合中并遍歷
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);
//得到大于25的流
Stream<Integer> age = set.stream().filter(s -> s > 25);
//把使用Stream流操作完畢的資料收集到Set集合中并遍歷
Set<Integer> a = age.collect(Collectors.toSet());
for (Integer i : a) {
System.out.println(i);
}
System.out.println("---------------------------");
//定義一個字串陣列,每個字串由姓名和年齡組合而成
String[] strArray = {"喬振宇,30", "劉德華,33", "周星馳,25", "吳孟達,35"};
//得到字串中年齡資料大于28的流
Stream<String> stream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);
//把使用Stream流操作完畢的資料收集到Map集合中并遍歷,字串中的姓名作鍵,年齡作值
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 = https://www.cnblogs.com/Hz-z/p/map.get(key);
System.out.println(key+","+value);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/163611.html
標籤:Java
