Java中Stream流的使用示例詳解
在 Java 中,Stream 流是 Java 8 引入的一個(gè)強(qiáng)大特性,它允許你以聲明式的方式處理集合數(shù)據(jù)。Stream 流提供了一種高效且易于使用的方式來(lái)對(duì)數(shù)據(jù)進(jìn)行過(guò)濾、映射、排序、聚合等操作,使代碼更加簡(jiǎn)潔和可讀。
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為變長(zhǎng)參數(shù)可以接收一個(gè)數(shù)組,但是這里只能接收引用類(lèi)型的數(shù)組,如果是基礎(chǔ)類(lèi)型的數(shù)據(jù)由于不會(huì)自動(dòng)裝包會(huì)把整個(gè)數(shù)組視為一個(gè)數(shù)據(jù)
2. 中間方法
當(dāng)我們獲取到Stream流后就可以調(diào)用其中的一些方法來(lái)對(duì)其中的數(shù)據(jù)進(jìn)行一些操作,其中的方法分為兩大類(lèi),其一就是中間方法,中間方法的特點(diǎn)是會(huì)返回一個(gè)新的 Stream 流,允許你鏈?zhǔn)秸{(diào)用多個(gè)操作 :
- Stream<T> filter(Predicate<T>):過(guò)濾滿(mǎn)足條件的元素。
- Stream<T> limit(long):限制元素?cái)?shù)量。
- Stream<T> skip(long):跳過(guò)前 n 個(gè)元素。
- Stream<T> distinct():去重。
- static<T> Stream<T> concat(Stream,Stream ):合并a和兩個(gè)流作為一個(gè)流
- Stream<T> sorted():排序。
- Stream<T> map(Function<T, R>):將元素轉(zhuǎn)換為另一種類(lèi)型。
注意:
- 每個(gè)Stream流只能使用一次,中間方法返回的是一個(gè)新的Stream流
- 修改Stream流中的數(shù)據(jù)不會(huì)影響原來(lái)集合或數(shù)組中的數(shù)據(jù)
2.1 filter使用示例
filter方法接收一個(gè)Predicate類(lèi)型的參數(shù),我們轉(zhuǎn)到其定義:

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

2.3 distinct 和concat
public static void distinctAndConcatTest() {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "張三豐", "張三豐", "楊過(guò)", "張明朱諾", "楊過(guò)", "小龍女");
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 + " "));
}運(yùn)行結(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ù)時(shí)默認(rèn)是排降序,可以傳入比較器自定義排序規(guī)則
2.5 map使用
public static void MapTest() {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "張明-16", "張三豐-23", "迪迦-3000");
//獲取每個(gè)人的年齡
/**
* 第一個(gè)參數(shù)對(duì)應(yīng)原本的數(shù)據(jù)類(lèi)型,第二個(gè)參數(shù)代表要轉(zhuǎn)成的數(shù)據(jù)類(lèi)型
*/
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表達(dá)式
list1.stream()
.map(s -> Integer.parseInt(s.split("-")[1]))
.forEach(x-> System.out.print(x + " "));
}運(yùn)行結(jié)果:

3. 終結(jié)方法
可以理解為結(jié)束方法,不會(huì)再返回Stream流
常用的終結(jié)方法有:
- forEach(Consumer<T>):遍歷每個(gè)元素。
- count():計(jì)算元素?cái)?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, "張三豐", "張三豐", "楊過(guò)", "張明朱諾", "楊過(guò)", "小龍女");
List<Integer> list2 = new ArrayList<>();
Collections.addAll(list2, 1, 2, 3);
System.out.println(list1.stream().count());
System.out.println(list2.stream().count());
//<>為需要?jiǎng)?chuàng)建的數(shù)組的類(lèi)型
String[] str = list1.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
//value代表數(shù)據(jù)的數(shù)量,我們返回一個(gè)長(zhǎng)度大于等于value的數(shù)據(jù)即可
return new String[value];
}
});
System.out.println(Arrays.toString(str));
//使用lambada表達(dá)式
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", "楊過(guò)-男-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表達(dá)式
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);
}這里特別說(shuō)明toMap()方法,

可以看到toMap接收兩個(gè)Function做為參數(shù),這里通過(guò)參數(shù)名我們不難猜出,一個(gè)作為鍵,一個(gè)作為值,于是我們只需實(shí)現(xiàn)Function接口重寫(xiě)其中方法使其返回預(yù)期的鍵/值即可。
到此這篇關(guān)于Java中Stream流的使用的文章就介紹到這了,更多相關(guān)java stream流使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis使用useGeneratedKeys獲取自增主鍵
這篇文章主要為大家介紹了Mybatis使用useGeneratedKeys獲取自增主鍵示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Java倒計(jì)時(shí)三種實(shí)現(xiàn)方式代碼實(shí)例
這篇文章主要介紹了Java倒計(jì)時(shí)三種實(shí)現(xiàn)方式代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Spring Boot 配置隨機(jī)數(shù)的技巧代碼詳解
這篇文章主要介紹了Spring Boot 配置隨機(jī)數(shù)技巧,spring boot 支持在系統(tǒng)加載的時(shí)候配置隨機(jī)數(shù),具體實(shí)例代碼大家參考下本文2018-05-05
簡(jiǎn)單聊一聊Java線(xiàn)程池ThreadPoolExecutor
在使用線(xiàn)程池之后,開(kāi)啟線(xiàn)程就變成了在線(xiàn)程池當(dāng)中找到一個(gè)空閑的線(xiàn)程,銷(xiāo)毀線(xiàn)程變成了歸還線(xiàn)程到線(xiàn)程池的過(guò)程,下面這篇文章主要給大家介紹了關(guān)于Java線(xiàn)程池ThreadPoolExecutor的相關(guān)資料,需要的朋友可以參考下2022-06-06
springboot整合token的實(shí)現(xiàn)代碼
這篇文章主要介紹了springboot整合token的實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
Java Swing實(shí)現(xiàn)讓窗體居中顯示的方法示例
這篇文章主要介紹了Java Swing實(shí)現(xiàn)讓窗體居中顯示的方法,結(jié)合實(shí)例形式分析了swing使用setBounds方法控制窗口布局的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
IDEA導(dǎo)入jar包的完整實(shí)現(xiàn)步驟
由于導(dǎo)入jar包項(xiàng)目存在很多不確定的問(wèn)題,導(dǎo)致每次都需要調(diào)試、配置好多遍,對(duì)此特意記錄下來(lái),這篇文章主要給大家介紹了關(guān)于IDEA導(dǎo)入jar包的相關(guān)資料,需要的朋友可以參考下2024-01-01
SpringBoot中Mybatis注解一對(duì)多和多對(duì)多查詢(xún)實(shí)現(xiàn)示例
這篇文章主要介紹了SpringBoot中Mybatis注解一對(duì)多和多對(duì)多查詢(xún)的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03

