Java中Stream流的使用示例詳解
在 Java 中,Stream 流是 Java 8 引入的一個強大特性,它允許你以聲明式的方式處理集合數(shù)據(jù)。Stream 流提供了一種高效且易于使用的方式來對數(shù)據(jù)進行過濾、映射、排序、聚合等操作,使代碼更加簡潔和可讀。
1. 獲取Stream流
要使用Stream流首先要獲取到Stream流
public static void main(String[] args) {
//創(chuàng)建Stream流
//1. 單列集合創(chuàng)建
List<String> list = new ArrayList<>();
Stream<?> stream1 = list.stream();
Set<String> set = new HashSet<>();
Stream<?> stream2 = set.stream();
Stack<String> stack = new Stack<>();
Stream<?> stream3 = stack.stream();
Queue<String> queue = new LinkedList<>();
Stream<?> stream4 = stack.stream();
//2. 雙列集合創(chuàng)建
Map<String, String> map = new HashMap<>();
Stream<?> stream5 = map.entrySet().stream();
//3. 數(shù)組創(chuàng)建
int[] arr = {1, 2 ,3};
IntStream stream6 = Arrays.stream(arr);
//4. 零散數(shù)據(jù)創(chuàng)建
Stream<?> stream7 = Stream.of(1, 2, 3, 4);
}注意 Stream.of(T... values) values為變長參數(shù)可以接收一個數(shù)組,但是這里只能接收引用類型的數(shù)組,如果是基礎(chǔ)類型的數(shù)據(jù)由于不會自動裝包會把整個數(shù)組視為一個數(shù)據(jù)
2. 中間方法
當我們獲取到Stream流后就可以調(diào)用其中的一些方法來對其中的數(shù)據(jù)進行一些操作,其中的方法分為兩大類,其一就是中間方法,中間方法的特點是會返回一個新的 Stream 流,允許你鏈式調(diào)用多個操作 :
- Stream<T> filter(Predicate<T>):過濾滿足條件的元素。
- Stream<T> limit(long):限制元素數(shù)量。
- Stream<T> skip(long):跳過前 n 個元素。
- Stream<T> distinct():去重。
- static<T> Stream<T> concat(Stream,Stream ):合并a和兩個流作為一個流
- Stream<T> sorted():排序。
- Stream<T> map(Function<T, R>):將元素轉(zhuǎn)換為另一種類型。
注意:
- 每個Stream流只能使用一次,中間方法返回的是一個新的Stream流
- 修改Stream流中的數(shù)據(jù)不會影響原來集合或數(shù)組中的數(shù)據(jù)
2.1 filter使用示例
filter方法接收一個Predicate類型的參數(shù),我們轉(zhuǎn)到其定義:

可以看到這是一個函數(shù)式接口, 同時test方法的描述也說明了,如果參數(shù)匹配則返回true否則返回false,這里的含義即為,如果該數(shù)據(jù)(t)是符合要求的則通過,否則不通過:
public static void filterTest() {
List<String> list = new ArrayList<>();
Collections.addAll(list, "張明", "張三豐", "張良", "張明朱諾", "楊過", "小龍女");
//這里篩選以張開頭且長度為3的字符串
list.stream()
.filter(s -> s.startsWith("張"))
.filter(s -> s.length() == 3)
.forEach(x-> System.out.print(x + " "));
}這里我們使用lambad表達式重寫test方法,先賽選了以張開頭的數(shù)據(jù),再賽選了長度為3的數(shù)據(jù)最后使用forEach輸出
2.2 limit 和skip使用
limit接收一個long類型的參數(shù)表示只保留前n個元素,skip同樣接收一個long類型的參數(shù)表示要跳過前n個元素:
public static void limitAndSkipTest() {
List<String> list = new ArrayList<>();
Collections.addAll(list, "張明", "張三豐", "張良", "張明朱諾", "楊過", "小龍女");
System.out.println("limit:");
list.stream()
.limit(4)
.forEach(x-> System.out.print(x + " "));
System.out.println("\nskip:");
list.stream()
.skip(3)
.forEach(x-> System.out.print(x + " "));
System.out.println("\nlimit-skip:");
list.stream()
.limit(4)
.skip(3)
.forEach(x-> System.out.print(x + " "));
System.out.println("\nskip-limit:");
list.stream()
.skip(3)
.limit(4)
.forEach(x-> System.out.print(x + " "));
}運行結(jié)果:

2.3 distinct 和concat
public static void distinctAndConcatTest() {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "張三豐", "張三豐", "楊過", "張明朱諾", "楊過", "小龍女");
List<String> list2 = new ArrayList<>();
Collections.addAll(list2, "張明", "張三豐", "迪迦");
System.out.println("\ndistinct:");
list1.stream()
.distinct()
.forEach(x-> System.out.print(x + " "));
System.out.println("\nconcat:");
Stream.concat(list1.stream(), list2.stream())
.forEach(x-> System.out.print(x + " "));
}運行結(jié)果:

2.4 stored使用
public static void sortedTest() {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "張明", "張三豐", "迪迦");
List<Integer> list2 = new ArrayList<>();
Collections.addAll(list2, 1, 2, 3);
System.out.println("\nsortedList1:");
list1.stream()
.sorted()
.forEach(x-> System.out.print(x + " "));
System.out.println("\nsortedList2:");
list2.stream()
.sorted()
.forEach(x-> System.out.print(x + " "));
System.out.println("\nsortedList2desc:");
list2.stream()
.sorted(((o1, o2) -> o2 - o1))
.forEach(x-> System.out.print(x + " "));
}sorted不傳參數(shù)時默認是排降序,可以傳入比較器自定義排序規(guī)則
2.5 map使用
public static void MapTest() {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "張明-16", "張三豐-23", "迪迦-3000");
//獲取每個人的年齡
/**
* 第一個參數(shù)對應(yīng)原本的數(shù)據(jù)類型,第二個參數(shù)代表要轉(zhuǎn)成的數(shù)據(jù)類型
*/
list1.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[1]);
}
}).forEach(x-> System.out.print(x + " "));
System.out.println();
//使用lambada表達式
list1.stream()
.map(s -> Integer.parseInt(s.split("-")[1]))
.forEach(x-> System.out.print(x + " "));
}運行結(jié)果:

3. 終結(jié)方法
可以理解為結(jié)束方法,不會再返回Stream流
常用的終結(jié)方法有:
- forEach(Consumer<T>):遍歷每個元素。
- count():計算元素數(shù)量。
- toArray():將元素轉(zhuǎn)換為數(shù)組。
- collect(Collector<T, A, R>):將元素收集到集合中。
3.1 forEach/count/toArray()使用
public static void CountAndToArrayTest() {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "張三豐", "張三豐", "楊過", "張明朱諾", "楊過", "小龍女");
List<Integer> list2 = new ArrayList<>();
Collections.addAll(list2, 1, 2, 3);
System.out.println(list1.stream().count());
System.out.println(list2.stream().count());
//<>為需要創(chuàng)建的數(shù)組的類型
String[] str = list1.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
//value代表數(shù)據(jù)的數(shù)量,我們返回一個長度大于等于value的數(shù)據(jù)即可
return new String[value];
}
});
System.out.println(Arrays.toString(str));
//使用lambada表達式
Integer[] arr = list2.stream().toArray(value -> new Integer[value]);
System.out.println(Arrays.toString(arr));
}3.2 collect 使用
將流中的元素收集到集合中
public static void CollectTest() {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "張三豐-男-23", "楊過-男-32", "張三豐-男-23", "張明朱諾-女-19", "小龍女-女-18");
//收集所有男性
//List
List<String> list = list1.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
System.out.println(list);
//Set
Set<String> set = list1.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(set);
//Map
//收集男性,名字作為鍵,年齡作為值
Map<String, Integer> map1 = list1.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.distinct()//map中key不能重復(fù),所以先去重
.collect(Collectors.toMap(
new Function<String, String>() {
@Override
public String apply(String s) {
return s.split("-")[0];
}
},
new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[2]);
}
}
));
System.out.println(map1);
//使用lambada表達式
Map<String, Integer> map2 = list1.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.distinct()//map中key不能重復(fù),所以先去重
.collect(Collectors.toMap(
s -> s.split("-")[0],
s -> Integer.parseInt(s.split("-")[2])
));
System.out.println(map2);
}這里特別說明toMap()方法,

可以看到toMap接收兩個Function做為參數(shù),這里通過參數(shù)名我們不難猜出,一個作為鍵,一個作為值,于是我們只需實現(xiàn)Function接口重寫其中方法使其返回預(yù)期的鍵/值即可。
到此這篇關(guān)于Java中Stream流的使用的文章就介紹到這了,更多相關(guān)java stream流使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java Socket無法完全接收返回內(nèi)容的解決方案
這篇文章主要介紹了java Socket無法完全接收返回內(nèi)容的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
一文詳解SpringBoot如何使用pageHelper做分頁處理
分頁是常見大型項目都需要的一個功能,PageHelper是一個非常流行的MyBatis分頁插件,下面就跟隨小編一起來了解下SpringBoot是如何使用pageHelper做分頁處理的吧2025-03-03
SpringBoot接口數(shù)據(jù)加解密實戰(zhàn)記錄
現(xiàn)今對于大多數(shù)公司來說,信息安全工作尤為重要,下面這篇文章主要給大家介紹了關(guān)于SpringBoot接口數(shù)據(jù)加解密的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-07-07
idea亂碼修改bin目錄下的idea.exe.vmoptions無效問題
這篇文章主要介紹了idea亂碼修改bin目錄下的idea.exe.vmoptions無效問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
SpringBoot整合Redis實現(xiàn)熱點數(shù)據(jù)緩存的示例代碼
這篇文章主要介紹了SpringBoot中整合Redis實現(xiàn)熱點數(shù)據(jù)緩存,本文以IDEA?+?SpringBoot作為?Java中整合Redis的使用?的測試環(huán)境,結(jié)合實例代碼給大家詳細講解,需要的朋友可以參考下2023-03-03
Maven項目中讀取src/main/resources目錄下的配置文件的方法
本篇文章主要介紹了Maven項目中讀取src/main/resources目錄下的配置文件的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12
Java 處理高并發(fā)負載類優(yōu)化方法案例詳解
這篇文章主要介紹了Java 處理高并發(fā)負載類優(yōu)化方法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08

