手把手帶你了解Java-Stream流方法學(xué)習(xí)及總結(jié)
前言
Stream是一個來自數(shù)據(jù)源的元素隊列并支持聚合操作,其中具有以下特性:
- Stream只負(fù)責(zé)計算,不存儲任何元素,元素是特定類型的對象,形成一個隊列
- 數(shù)據(jù)源可以實集合、數(shù)組、I/O channel、generator等
- 聚合操作有類似SQL的:filter、map、match、sorted等操作
- Stream流的執(zhí)行類似于懶加載,用戶使用時才執(zhí)行相應(yīng)操作
- 可消費性;Stream只能被消費一次,被消費后需要重新生成
本文總結(jié)了部分在日常開發(fā)中經(jīng)常接觸到的一些Stream流相關(guān)的方法,不足之處或有錯誤歡迎留評,總結(jié)的幾個方法如下:
- void forEach() : 迭代流中的數(shù)據(jù)
- Stream map() : 用于映射每個元素到對應(yīng)的結(jié)果
- Stream filter() : 條件過濾器
- Stream sorted() : 排序
- R collect() : 流數(shù)據(jù) -> 集合/數(shù)組
- 待補充…
forEach()
forEach()源碼:
void forEach(Consumer<!--? super T--> action);
Stream().forEach() : 迭代流中的數(shù)據(jù)
forEach() 的返回類型為void,不會產(chǎn)生新的流
舉個栗子:
public void testForEach() {
/**
* 使用forEach()內(nèi)部迭代
* ints()表示整數(shù)類型
* limit()表示限制流個數(shù)(次數(shù))
*/
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
}
運行結(jié)果:

再舉個靈活一點的栗子:
public void testForEach() {
/**
* 使用forEach()轉(zhuǎn)換集合類型,如List->Map
*/
AtomicInteger i = new AtomicInteger();//原子類型
Map<Integer,String> map = new HashMap<>();
List<String> list = new ArrayList<>(Arrays.asList("Hello",",","world"));
list.stream().forEach(s->{
map.put(i.getAndIncrement(),s);
});
}
對于forEach()方法在本人日常開發(fā)中常用于:
- 使用內(nèi)循環(huán)對集合進行遍歷
- 使用foreach方法將List轉(zhuǎn)為Map形式
map()
map()源碼:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Stream().map() 用于映射每個元素到對應(yīng)的結(jié)果
返回類型為Stream,map()會產(chǎn)生新的流并返回
舉個栗子:
public void testMap(){
/**
* map()獲取list每個元素的平方值
* distinct()去重操作
* collect()將map()產(chǎn)生的新的流轉(zhuǎn)為List類型
*/
List<Integer> list = Arrays.asList(1,2,3);
list.stream().map(num -> num * num)
.distinct()
.collect(Collectors.toList())
.forEach(System.out::println);
}
filter()
filter()源碼:
Stream<T> filter(Predicate<? super T> predicate);
Stream().filter()為條件過濾器
舉個栗子:
public void testFilter(){
/**
* filter()過濾空字符串
* count()統(tǒng)計符合條件的個數(shù),返回類型long
*/
List<String> list = new ArrayList<>(Arrays.asList("ab","","abc","","acd"));
long count = list.stream()
.filter(str -> str.isEmpty())
.count();
}
sorted()
sorted()源碼:
Stream<T> sorted(); Stream<T> sorted(Comparator<? super T> comparator);
Stream支持兩種方式的排序:
無參方法默認(rèn)為自然排序sorted(Comparator comp) 按自定義比較器進行排序
仍然是舉個栗子:
1)無參方法
public void testSorted(){
/**
* sort()無參默認(rèn)為自然排序
* 返回類型Stream 會產(chǎn)生新的流
*/
List<String> list = new ArrayList<>(Arrays.asList("aaa","ccc","bbb"));
list.stream().sorted().forEach(System.out::println);
}
執(zhí)行結(jié)果:

2)帶參方法(User類由name和age組成)
- 先比較年齡,按從小到大排序
- 若年齡相等,則按性名自然排序
public void testSorted(){
/**
* sort(Comparator comp)按自定義比較器進行排序
* 返回類型同樣是Stream 會產(chǎn)生新的流
*/
List<User> userList = new ArrayList<>(Arrays.asList(
new User("zhangsan",22),
new User("wangwu",22),
new User("badao",32),
new User("kongfu",16)
));
Stream<User> sorted = userList.stream().sorted((x, y) -> {
if (x.getAge() == y.getAge()) { // 使用流中的序列兩兩進行比較
return x.getName().compareTo(y.getName());
} else {
return x.getAge() - y.getAge();//順序
// y.getAge() - x.getAge() 為逆序
}
});
sorted.forEach(System.out::println);
}
執(zhí)行結(jié)果:

collect()
collect()源碼:
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
stream().collect() 由三個參數(shù)構(gòu)成 :
1.Supplier 生產(chǎn)者,返回最終
2.結(jié)果BiConsumer<R, ? super T> accumulator,累加器 :
其中 R 為要返回的集合, ? super T 為遍歷過程中的每個參數(shù),相當(dāng)于add操作
3.BiConsumer<R,R> combiner,合并器 :
有并行流時才會使用,相當(dāng)于將第二部操作形成的list添加到最終的list,addAll操作
舉個栗子:
1)new()
public void testCollect(){
Stream<String> stream = Stream.of("hello","world","hello,world");
// new()
List<String> list = stream.collect(Collectors.toList());//List
// 指定集合類型,如ArrayList
ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
//Set
stream.collect(Collectors.toSet());
// 指定HashSet
HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
// 拼接字符串
String str = stream.collect(Collectors.joining());
2)new() -> add() -> addAll()
public void testCollect(){
/**
* 參數(shù)傳遞行為相當(dāng)于: new() -> add() -> addAll()
*/
Stream<String> stream = Stream.of("hello","world","hello,world");
// new() -> add() -> addAll()完整演示
HashMap<String,String> map = stream.collect(HashMap::new,(x,y)->{
x.put(y,y); // x 為集合,y 為當(dāng)前遍歷元素,以當(dāng)前遍歷元素作為kv
},HashMap::putAll);
map.forEach((x,y)->{
System.out.println(x+" : "+y);
});
執(zhí)行結(jié)果:

總結(jié)
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
SpringBoot多環(huán)境開發(fā)與日志小結(jié)
這篇文章主要介紹了SpringBoot多環(huán)境開發(fā)與日志,下面給大家說一下如何基于多環(huán)境開發(fā)做配置獨立管理,務(wù)必掌握,需要的朋友可以參考下2022-08-08
SpringBoot的配置文件application.yml及加載順序詳解
這篇文章主要介紹了SpringBoot的配置文件application.yml及加載順序,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
JAVA調(diào)用SAP WEBSERVICE服務(wù)實現(xiàn)流程圖解
這篇文章主要介紹了JAVA調(diào)用SAP WEBSERVICE服務(wù)實現(xiàn)流程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
使用自定義參數(shù)解析器同一個參數(shù)支持多種Content-Type
這篇文章主要介紹了使用自定義參數(shù)解析器同一個參數(shù)支持多種Content-Type的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
Intellij idea下使用不同tomcat編譯maven項目的服務(wù)器路徑方法詳解
今天小編就為大家分享一篇關(guān)于Intellij idea下使用不同tomcat編譯maven項目的服務(wù)器路徑方法詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-02-02
IntelliJ IDEA 小技巧之Bookmark(書簽)的使用
這篇文章主要介紹了IntelliJ IDEA 小技巧之Bookmark(書簽)的使用,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
javafx 如何將項目打包為 Windows 的可執(zhí)行文件exe
文章介紹了三種將JavaFX項目打包為.exe文件的方法:方法1使用jpackage(適用于JDK14及以上版本),方法2使用Launch4j(適用于所有JDK版本),方法3使用InnoSetup(用于創(chuàng)建安裝包),每種方法都有其特點和適用范圍,可以根據(jù)項目需求選擇合適的方法,感興趣的朋友一起看看吧2025-01-01

