【Java29】Stream流
阿新 • • 發佈:2021-01-20
文章目錄
1.Stream流引入
package com.itheima07.boot;
import java.util.ArrayList;
import java.util.List;
// 程式碼冗餘: 1. 迴圈太多 2. 判斷太多
public class StreamBootDemo {
public static void main(String[] args) {
List< String> list = new ArrayList<>();
list.add("張無忌");
list.add("周芷若");
list.add("趙敏");
list.add("張強");
list.add("張三丰");
//張集合
List<String> zhangList = new ArrayList<>();
for (String name : list) {
if (name.startsWith("張")) {
zhangList.add(name);
}
}
//短集合 : 張集合基礎上,只要名字3個
List<String> shortList = new ArrayList<>();
for (String name : zhangList) {
if (name.length() == 3 ) {
shortList.add(name);
}
}
for (String name : shortList) { //遍歷列印
System.out.println(name);
}
}
}
package com.itheima07.boot;
import java.util.ArrayList;
import java.util.List;
// Stream 流: 1. 基於函數語言程式設計延伸出來的一種用法。 2. 作用: 簡化 集合資料 處理過程中的程式碼冗餘問題
public class StreamBootDemo02 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("張無忌");
list.add("周芷若");
list.add("趙敏");
list.add("張強");
list.add("張三丰");
list.stream().filter(name -> name.startsWith("張")) //name就是集合中的每個元素
.filter(name -> name.length() == 3).forEach(name-> System.out.println(name));
}
}
2.Stream流的獲取
如下排除靜態方法,ArrayList能用stream方法的話,是從Collection裡繼承這方法
package com.itheima08.stream;
import com.sun.org.apache.bcel.internal.generic.NEW;
import java.util.*;
import java.util.stream.Stream;
/*
* Stream 流: Stream流物件的獲取:
* 1. 集合
* Collection介面 預設方法 stream()
* 2. 陣列
* Stream.of(T...); 使用這個
* Stream.of(T);
*/
public class StreamGetDemo {
public static void main(String[] args) {
Collection<String> coll = new HashSet<>();
Stream<String> stream = coll.stream();
//1111111111111111111111111111111111111111111111111111111111111111111111111111
HashMap<String, String> map = new HashMap<>();
// Set set = map.keySet();
// set.stream();
Stream<String> stream1 = map.keySet().stream();
Stream<Map.Entry<String, String>> stream2 = map.entrySet().stream();
//111111111111111111111111111111111111111111111111111111111111111111111111111
String[] array = {"a","b"};
Stream<String> stream3 = Stream.of(array);
Integer[] array2 = {1,2,3};
Stream<Integer> stream4 = Stream.of(array2); //T... -> T=Integer,把每個元素拆開。//泛型 必須是 引用型別
int[] array3 = {1,2,3};
//如果說陣列要獲取Stream流,不要用基本型別陣列, 把整個陣列當成一個元素無法拆開,不要用如下
Stream<int[]> stream5 = Stream.of(array3);// T -> T = int[]
}
}
3.Stream流的終結方法
package com.itheima09.method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Consumer;
/*
* Stream流的方法
* 1. 終結方法 : 不支援鏈式程式設計 (返回值: 基本型別)
* 2. 拼接方法 : 支援鏈式程式設計 (返回值: 當前型別,引用型別)
*
* 終結方法:
* 1.foreach
* void forEach(Consumer<? super T> action);
* 底層: 迭代器 , 需要消費引數(集合中每一個元素)
* 2.count
* long count() : 獲取集合中的元素個數
*/
public class EndDemo {
public static void main(String[] args) {
// method();
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 5,3,2,4);
// for (Integer integer : list) { //list.for快捷
// System.out.println(integer);
// }
//11111111111111111111111111111111111111111111111111111111111111111111
//stream流列印,先獲取stream流物件
/* list.stream().forEach(new Consumer<Integer>() {
@Override
public void accept(Integer t) {
System.out.println(t); //遍歷列印list集合
}
});*/
//如下等於上面
// list.stream().forEach(t-> System.out.println(t));
//11111111111111111111111111111111111111111111111111111111111111111111
long count = list.stream().count();
System.out.println(count); //4
}
private static void method() {
// StringBuilder sb = new StringBuilder();
// StringBuilder sb2 = sb.append("a");
// StringBuilder sb3 = sb2.append("b");
StringBuilder sb = new StringBuilder();
//append拼接方法,equals終結方法,因為equals返回boolean基本型別,不能再呼叫方法
sb.append("a").append("b").append("c").equals("abc");
}
}
4.Stream流的拼接方法
package com.itheima09.method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.function.Predicate;
import java.util.stream.Stream;
/*
* Stream的拼接方法
* 1. filter 過濾
* Stream<T> filter(Predicate<? super T> predicate);
* 1. Predicate : public boolean test(String s)
* 2. s是集合中每一個元素 , 迭代器
* 3. return true : 表示保留這個元素
* 2. limit 取用前幾個
* Stream<T> limit(long count)
* 只要前count個元素, 沒有越界
* 3. skip 跳過前幾個
* Stream<T> skip(long n);
* 4. static concat 組合,靜態方法
* static <T> Stream<T> concat(Stream<T> a, Stream< T> b)
* 合併兩個stream,整合一個stream
*/
public class ChainDemo { //Chain:鏈
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"張三","張三丰","李四","李世石");
//.filter返回值型別是stream,調完filter還能調filter,就像Stringbuild調完append還可再調append
// list.stream().filter(new Predicate<String>() {
// @Override
// public boolean test(String s) {
// return s.startsWith("張");
// }
// }).forEach(s -> System.out.println(s)); //張三 張三丰
// list.stream().filter(s->s.startsWith("張")).forEach(s-> System.out.println(s)); //等同上面
// list.stream().limit(5).forEach(t-> System.out.println(t)); //沒有索引越界,因為迭代器沒有索引,最多4個就給4個
// list.stream().skip(3).forEach(t-> System.out.println(t)); //李世石
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2,"王五","王五百","馬六");
Stream<String> stream1 = list.stream();
Stream<String> stream2 = list2.stream();
Stream.concat(stream1,stream2).forEach(t-> System.out.println(t)); //張三...7個元素
}
}
5.Stream原始碼分析
package com.itheima10.source;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class MyStream {
Collection<String> coll; //屬性
public MyStream(Collection<String> coll){
this.coll = coll;
}
public void forEach(Consumer<String> consumer){
for (String s : coll) { //快捷鍵coll.foreach
consumer.accept(s); //介面呼叫方法執行子類重寫的方法即下面SourceDemo.java中System.out.println(t),s就是t,
}
}
public MyStream filter(Predicate<String> predicate){
ArrayList<String> list = new ArrayList<>(); //list集合只新增 推斷結果true的元素,新的
for (String s : coll) {
boolean result = predicate.test(s); //父類引用呼叫方法執行子類重寫方法即下面SourceDemo.java中t.length()==2
if(result){
list.add(s);
}
}
coll = list; //集合重置為list即保留下來的集合
return this;
}
}
package com.itheima10.source;
import java.util.ArrayList;
import java.util.Collections;
public class SourceDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"張三","李四光","王五");
/*
* foreach:
* 1. 迭代器(底層)
* 2. t是集合中的每一個元素
* 執行次數 = 集合元素個數
*/
// new MyStream(list).forEach(t -> System.out.println(t));
/*
* MyStream filter(Predicate<String> predicate)
* predicate : boolean test(T t);
* 1. 迭代器
* 2. t 是集合中的每一個元素
* 3. 返回true : 表示保留這個元素
*/
new MyStream(list).filter(t -> t.length()==2).forEach(t-> System.out.println(t));
}
}
6.綜合案例
package com.itheima11.union;
import java.util.ArrayList;
import java.util.List;
public class Demo01 {
public static void main(String[] args) {
List<String> one = new ArrayList<>();
one.add("迪麗熱巴");
one.add("宋遠橋");
one.add("蘇星河");
one.add("老子");
one.add("莊子");
one.add("孫子");
one.add("洪七公");
List<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("張無忌");
two.add("張三丰");
two.add("趙麗穎");
two.add("張二狗");
two.add("張天愛");
two.add("張三");
List<String> oneA = new ArrayList<>(); // 第一個隊伍只要名字為3個字的成員姓名;
for (String name : one) {
if (name.length() == 3) {
oneA.add(name);
}
}
List<String> oneB = new ArrayList<>(); // 第一個隊伍篩選之後只要前3個人;
for (int i = 0; i < 3; i++) {
oneB.add(oneA.get(i));
}
//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111
List<String> twoA = new ArrayList<>(); // 第二個隊伍只要姓張的成員姓名;
for (String name : two) {
if (name.startsWith("張")) {
twoA.add(name);
}
}
List<String> twoB = new ArrayList<>(); // 第二個隊伍篩選之後不要前2個人;
for (int i = 2; i < twoA.size(); i++) {
twoB.add(twoA.get(i));
}
//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111
List<String> totalNames = new ArrayList<>(); // 將兩個隊伍合併為一個隊伍;
totalNames.addAll(oneB);
totalNames.addAll(twoB);
for (String name : totalNames) { // 列印整個隊伍的姓名資訊。
System.out.println(name);
}
}
}
package com.itheima11.union;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class Demo02 {
public static void main(String[] args) {
List<String> one = new ArrayList<>();
one.add("迪麗熱巴");
one.add("宋遠橋");
one.add("蘇星河");
one.add("老子");
one.add("莊子");
one.add("孫子");
one.add("洪七公");
List<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("張無忌");
two.add("張三丰");
two.add("趙麗穎");
two.add("張二狗");
two.add("張天愛");
two.add("張三");
//stream流式程式設計核心:隱藏了沒有必要的迴圈迭代,把最核心的條件暴露出來並通過鏈式程式設計方式把程式碼順起來
// 1. 第一個隊伍只要名字為3個字的成員姓名;
// 2. 第一個隊伍篩選之後只要前3個人;
Stream<String> stream1 = one.stream().filter(s -> s.length() == 3).limit(3);
// 3. 第二個隊伍只要姓張的成員姓名;
// 4. 第二個隊伍篩選之後不要前2個人;
Stream<String> stream2 = two.stream().filter(s -> s.startsWith("張")).skip(2);
// 5. 將兩個隊伍合併為一個隊伍;
// 6. 列印整個隊伍的姓名資訊。
Stream.concat(stream1,stream2).forEach(t-> System.out.println(t));
}
}
B站/知乎/微信公眾號:碼農程式設計錄