體驗Stream流
- Stream流一般配合Lamda運算式使用
- 函式式編程
- 通過字面意思即可展示無關邏輯的陳述句

public class Demo {
public static void main(String[] args) {
//創建集合,存盤多個字串元素
ArrayList<String> list = new ArrayList<>();
list.add("張三豐");
list.add("李白");
list.add("王二");
list.add("張譯");
list.add("馬文才");
list.add("張懷民");
//創建新集合,以存盤“張”開頭的元素
ArrayList<String> zhang = new ArrayList<>();
for (String s : list) {
if (s.startsWith("張")){
zhang.add(s);
}
}
//創建新集合,以存盤“張”開頭的長度為3的元素
ArrayList<String> zhangSan = new ArrayList<>();
for (String s : zhang) {
if (s.length()==3){
zhangSan.add(s);
}
}
//遍歷集合
for (String s : zhangSan) {
System.out.println(s);
}
}
}
運行結果:
張三豐
張懷民
不難看出,代碼過長且重復度過高;通過Stream流改進
public class Demo {
public static void main(String[] args) {
//創建集合,存盤多個字串元素
ArrayList<String> list = new ArrayList<>();
list.add("張三豐");
list.add("李白");
list.add("王二");
list.add("張譯");
list.add("馬文才");
list.add("張懷民");
//使用Stream和方法參考改進
list.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(System.out::println);
}
}
運行結果:
張三豐
張懷民
Stream流的生成方式
Stream流的使用
- 生成流
通過資料源生成流
如:list.stream()- 中間操作
一個流后面可以跟多個中間操作
如:filter()
如:filter().filter()- 終結操作
一個流只能有一個終結操作
如:forEach()
Stream流的常見生成方式

public class Demo1 {
public static void main(String[] args) {
//Collection體系的集合,使用默認方法stream()生成流
ArrayList<String> list = new ArrayList<>();
Stream<String> listStream = list.stream();
HashSet<String> set = new HashSet<>();
Stream<String> setStream = set.stream();
//Map體系集合,間接生成流
HashMap<String, String> map = new HashMap<>();
//鍵的流
Stream<String> keyStream = map.keySet().stream();
//值的流
Stream<String> valueStream = map.values().stream();
//鍵值對物件的流
Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
//陣列通過Stream介面的靜態方法of(T... values)生成流
String[] strArr = {"hello","world","java"};
//of中的引數可變
Stream<String> strArrStream = Stream.of(strArr);
Stream<String> strArrStream1 = Stream.of("hello","world","java");
Stream<Integer> strArrStream2 = Stream.of(10,20,33);
}
}
Stream流中間操作
- 以Stream開頭的陳述句,做了終結操作之后,就不能再次開始;否則會報錯,
- 以資料源開始轉為stream流的陳述句,做了終結操作之后,還可以再次以資料源開始做操作


filter

public class Demo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("張三豐");
list.add("李白");
list.add("王二");
list.add("張譯");
list.add("馬文才");
list.add("張懷民");
//輸出“張”開頭的元素
list.stream().filter(s -> s.startsWith("張")).forEach(System.out::println);
System.out.println("----------------");
//輸出長度為3的元素
list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
System.out.println("----------------");
//輸出“張”開頭,并且長度為3的元素
list.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(System.out::println);
}
}
運行結果:
張三豐
張譯
張懷民
----------------
張三豐
馬文才
張懷民
----------------
張三豐
張懷民
limit & skip


public class Demo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("張三豐");
list.add("李白");
list.add("王二");
list.add("張譯");
list.add("馬文才");
list.add("張懷民");
//輸出前3個元素
list.stream().limit(3).forEach(System.out::println);
System.out.println("-------------");
//輸出除了前3個元素以外的元素
list.stream().skip(3).forEach(System.out::println);
System.out.println("-------------");
//跳過前2個元素,輸出接下來的2個元素
list.stream().skip(2).limit(2).forEach(System.out::println);
}
}
運行結果:
張三豐
李白
王二
-------------
張譯
馬文才
張懷民
-------------
王二
張譯
concat & distinct

public class Demo2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("張三豐");
list.add("李白");
list.add("王二");
list.add("張譯");
list.add("馬文才");
list.add("張懷民");
//需求1:獲取前4個元素,組成一個流
Stream<String> s1 = list.stream().limit(4);
//需求2:跳過2個元素,組成一個流
Stream<String> s2 = list.stream().skip(2);
//需求3:合并需求1和需求2的流,輸出
//Stream.concat(s1,s2).forEach(System.out::println);
//需求4:合并需求1和需求2的流,輸出,要求字串元素不能重復
Stream.concat(s1,s2).distinct().forEach(System.out::println);
}
}
運行結果:
張三豐
李白
王二
張譯
馬文才
張懷民
sorted

public class Demo3 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("libai");
list.add("yangyuhuan");
list.add("wuzetian");
list.add("zhaohuaizhen");
list.add("sikongzhen");
list.add("shangguanwaner");
//需求1:按照字母順序輸出資料
list.stream().sorted().forEach(System.out::println);
System.out.println("------------");
//需求2:按照字串長度輸出資料
list.stream().sorted((s1, s2) -> s1.length() - s2.length()).forEach(System.out::println);
System.out.println("------------");
//需求3:按照字串長度輸出資料,長度相同時自然排序
list.stream().sorted((s1, s2) -> {
int num = s1.length() - s2.length();
int num2 = num == 0 ? s1.compareTo(s2) : num;
return num2;
}).forEach(System.out::println);
}
}
運行結果:
libai
shangguanwaner
sikongzhen
wuzetian
yangyuhuan
zhaohuaizhen
------------
libai
wuzetian
yangyuhuan
sikongzhen
zhaohuaizhen
shangguanwaner
------------
libai
wuzetian
sikongzhen
yangyuhuan
zhaohuaizhen
shangguanwaner
map & mapToInt

Stream流呼叫了mapToInt()方法,就會變成IntStream流
IntStream流可以呼叫sum()方法
public class Demo4 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("10");
list.add("20");
list.add("30");
list.add("40");
list.add("50");
//需求:使用map()將集合中的字串轉為整數后輸出
list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println);
System.out.println("-----------");
//方法參考
list.stream().map(Integer::parseInt).forEach(System.out::println);
System.out.println("-----------");
//需求2:使用mapToInt()將集合中的字串轉為整數后輸出
list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
System.out.println("-----------");
//需求3:使用IntStream()中的sum(),回傳int元素的總和,輸出結果
System.out.println(list.stream().mapToInt(Integer::parseInt).sum());
}
}
運行結果:
10
20
30
40
50
-----------
10
20
30
40
50
-----------
10
20
30
40
50
-----------
150
Stream流常見的終結操作方法

forEach & count
public class Demo5 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("張三豐");
list.add("李白");
list.add("王二");
list.add("張譯");
list.add("馬文才");
list.add("張懷民");
//需求1:輸出集合中的元素
list.stream().forEach(System.out::println);
//需求1:統計以“張”開頭的元素,輸出統計結果
System.out.println(list.stream().filter(s -> s.startsWith("張")).count());
}
}
運行結果:
張三豐
李白
王二
張譯
馬文才
張懷民
3
綜合練習


public class Demo6 {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
list1.add("馬保國");
list1.add("陳龍");
list1.add("張豐毅");
list1.add("胡歌");
list1.add("李永健");
list1.add("趙本山");
ArrayList<String> list2 = new ArrayList<>();
list2.add("林黛玉");
list2.add("劉亦菲");
list2.add("陶虹");
list2.add("宋佳");
list2.add("林心如");
list2.add("張嘉倪");
//男演員只要名字為三個字的前3人
Stream<String> man = list1.stream().filter(s -> s.length() == 3).limit(3);
//女演員只要姓林的,并且不要第一個
Stream<String> women = list2.stream().filter(s -> s.startsWith("林")).skip(1);
//把man和women合并在一起
Stream<String> concat = Stream.concat(man, women);
//將concat中的元素作為構造方法的引數,創建物件,遍歷資料
concat.map(Actor::new).forEach(s-> System.out.println(s.getName()));
}
}
運行結果:
馬保國
張豐毅
李永健
林心如
收集操作

將流中的資料存入集合
public class Demo6 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("馬保國");
arrayList.add("陳龍");
arrayList.add("張豐毅");
arrayList.add("胡歌");
arrayList.add("李永健");
arrayList.add("張擇端");
//需求1:以流的方式拿到以“張”開頭的元素,
Stream<String> strStream = arrayList.stream().filter(s -> s.startsWith("張"));
//需求2:將流收集到list集合,并遍歷集合
List<String> list = strStream.collect(Collectors.toList());
for (String s : list) {
System.out.println(s);
}
System.out.println("------");
HashSet<Integer> hashSetset = new HashSet<>();
hashSetset.add(10);
hashSetset.add(20);
hashSetset.add(30);
hashSetset.add(33);
hashSetset.add(35);
//需求3:獲取大于25的元素
Stream<Integer> setStream = hashSetset.stream().filter(s -> s > 25);
//需求4:將流收集到set集合,并遍歷
Set<Integer> set = setStream.collect(Collectors.toSet());
for (Integer i : set) {
System.out.println(i);
}
}
}
運行結果:
張豐毅
張擇端
------
33
35
30
public class Demo6 {
public static void main(String[] args) {
String[] str = {"張藝興,11","劉強東,29","朱之文,33","高啟強,28"};
//需求1:獲取年齡大于28的元素
Stream<String> stringStream = Stream.of(str).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);
//需求2:把流存入Map集合,并遍歷
Map<String, Integer> map = stringStream.collect(Collectors.toMap(s -> s.split(",")[0],
s -> Integer.parseInt(s.split(",")[1])));
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + "-" + entry.getValue());
}
}
}
運行結果:
朱之文-33
劉強東-29
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/543498.html
標籤:Java
