1.Stream API 介紹
Java8 版本引入的重要特性之一, 對(duì)于集合(例如 List、Map、Set 等)進(jìn)行處理和操作的高級(jí)抽象.Stream API 提供了一種更為簡(jiǎn)潔高效的的方式來(lái)處理集合數(shù)據(jù), 可讀性較高, 特別在數(shù)據(jù)的過(guò)濾、轉(zhuǎn)換、聚合時(shí)的操作很簡(jiǎn)單方便快捷.
1.1 特點(diǎn)與優(yōu)勢(shì)
- 函數(shù)式風(fēng)格: Stream API使用函數(shù)式接口和Lambda表達(dá)式, 讓代碼更具表達(dá)力和簡(jiǎn)潔性.
- 惰性求值: Stream操作通常是惰性求值的, 這意味著在終端操作之前, 中間操作不會(huì)立即執(zhí)行, 從而提高了效率.
- 并行處理: 通過(guò)Stream API可以方便地實(shí)現(xiàn)并行處理, 從而充分利用多核處理器的優(yōu)勢(shì), 加速處理大量數(shù)據(jù)的過(guò)程.
下面根據(jù)一些實(shí)際應(yīng)用場(chǎng)景來(lái)分析
1.2 兩大類(lèi)型
- 中間操作(Intermediate Operations):中間操作是指在Stream上執(zhí)行的操作, 它們返回一個(gè)新的Stream, 允許你鏈?zhǔn)降剡M(jìn)行多個(gè)中間操作.
- 終端操作(Terminal Operations):對(duì)Stream進(jìn)行最終處理的操作, 當(dāng)調(diào)用終端操作時(shí), Stream會(huì)開(kāi)始執(zhí)行中間操作, 并生成最終的結(jié)果或副作用.終端操作是Stream的"觸發(fā)器", 一旦調(diào)用終端操作, Stream就不能再被使用, 也不能再進(jìn)行中間操作.
2.Stream API 中間操作
2.1 filter(條件)
用于根據(jù)指定條件過(guò)濾元素.它接收一個(gè)條件作為參數(shù), 只保留滿足條件的元素, 并生成一個(gè)新的Stream.
示例:
存在一個(gè)姓名的集合,現(xiàn)在要過(guò)濾出來(lái)名字中帶【大】的人員.
public static void main(String[] args) {
List<String> tempList = Arrays.asList("劉一手", "杜子騰", "林大蛋", "Ekko");
List<String> resList = tempList.stream()
.filter(s -> s.contains("大"))
.collect(Collectors.toList());
System.out.println(resList.toString());
}
輸出:
[林大蛋]
這段Java代碼展示了如何使用Java Stream API對(duì)一個(gè)字符串列表進(jìn)行處理,并篩選出包含字符"大"的字符串,然后將篩選后的結(jié)果收集到一個(gè)新的列表中,最后輸出結(jié)果。
讓我們逐步解釋這段代碼:
首先我們創(chuàng)建了一個(gè)包含四個(gè)字符串的集合,后使用 Stream API 對(duì) tempList 進(jìn)行處理。
首先,通過(guò)調(diào)用stream()方法,將tempList轉(zhuǎn)換為一個(gè)Stream。
接著,使用filter中間操作篩選出包含字符"大"的字符串。
這里的filter方法接收一個(gè)Lambda表達(dá)式作為參數(shù),Lambda 表達(dá)式s -> s.contains("大")
用于判斷字符串是否包含字符"大"。
只有滿足條件的字符串會(huì)被保留在Stream中。
collect(Collectors.toList())這部分是終端操作,它將Stream中的元素收集到一個(gè)新的列表中。在這里,我們使用Collectors.toList()方法來(lái)將Stream中的篩選結(jié)果收集到一個(gè)新的List中,賦值給resList。
2.2 map(函數(shù))
用于對(duì)每個(gè)元素執(zhí)行映射操作, 將元素轉(zhuǎn)換成另一種類(lèi)型.它接收一個(gè)Function(映射函數(shù))作為參數(shù), 對(duì)每個(gè)元素應(yīng)用該映射函數(shù), 并生成一個(gè)新的Stream.
示例:
存在一個(gè)姓名的集合,現(xiàn)在要給所有名字加上姓名的前綴.
public static void main(String[] args) {
List<String> tempList = Arrays.asList("劉一手", "杜子騰", "林大蛋", "Ekko");
List<String> resList = tempList.stream()
.map(s -> "姓名: " + s)
.collect(Collectors.toList());
System.out.println(resList.toString());
}
輸出:
[姓名: 劉一手, 姓名: 杜子騰, 姓名: 林大蛋, 姓名: Ekko]
這段代碼的意思是創(chuàng)建一個(gè)姓名集合,通過(guò)stream()方法把集合轉(zhuǎn)換為 Stream 流,通過(guò) map() 方法給每個(gè)集合中的值拼接字符串后,使用collect()方法把這些元素歸集到一個(gè)新的 List 集合并賦值給 resList.
這里的
.map(s -> "姓名: " + s)
是簡(jiǎn)寫(xiě),詳細(xì)的更容易理解的寫(xiě)法如下:.map(s -> {
return "姓名: " + s;
})
2.3 flatMap(函數(shù))
類(lèi)似于map操作,但是 flatMap 操作可以將每個(gè)元素映射成一個(gè) Stream,然后把所有生成的 Stream 合并成一個(gè)新的Stream。
示例:
新建一個(gè)靜態(tài)內(nèi)部類(lèi), 然后聚合類(lèi)中的集合數(shù)據(jù)
@Data
static class Personnel {
// 人員姓名
private String name;
// 人員標(biāo)簽
private List<String> tagList;
public Personnel(String name, List<String> tagList) {
this.name = name;
this.tagList = tagList;
}
}
Tips: 就現(xiàn)在想要把 List<Personnel>
中的 tagList
聚合后進(jìn)行處理, 代碼如下:
public static void main(String[] args) {
Personnel personA = new Personnel("張三", Arrays.asList("抽煙", "喝酒", "燙頭"));
Personnel personB = new Personnel("李斯", Arrays.asList("編碼", "喝酒", "踢足球"));
List<Personnel> personnelList = Arrays.asList(personA, personB);
personnelList.stream()
.flatMap(p -> p.getTagList().stream())
.forEach(s -> System.out.print(s + " "));
}
輸出:
抽煙 喝酒 燙頭 編碼 喝酒 踢足球
2.4 sorted()
用于對(duì)Stream中的元素進(jìn)行排序,默認(rèn)按照自然順序進(jìn)行排序。也可以傳入自定義的Comparator來(lái)指定排序規(guī)則。
示例:
public class SortedTest {
public static void main(String[] args) {
List<Integer> numList = Arrays.asList(10, 20, 18, 300, 30, 2);
// ① 默認(rèn)排序
List<Integer> orderList = numList.stream()
.sorted()
.collect(Collectors.toList());
System.out.printf("① 默認(rèn)排序: %s%n", orderList);
// ② 自定義排序
List<Integer> orderDescList = numList.stream()
.sorted((x, y) -> {
return y.compareTo(x);
})
.collect(Collectors.toList());
System.out.printf("② 自定義排序: %s%n", orderDescList);
}
}
輸出:
① 默認(rèn)排序: [2, 10, 18, 20, 30, 300]
② 自定義排序: [300, 30, 20, 18, 10, 2]
關(guān)于
return y.compareTo(x);
這塊的具體意義,可以自行搜索compareTo
方法了解下,這里不做單獨(dú)贅述
2.5 distinct()
用于去除 Stream 中重復(fù)的元素,確保最終的 Stream 中每個(gè)元素都是唯一的。
示例:
public class DistinctStreamTest {
public static void main(String[] args) {
List<Integer> numList = Arrays.asList(1,1,1,1,2,3,2,2);
List<Integer> distinctList = numList.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctList);
}
}
輸出:
[1, 2, 3]
這段代碼先創(chuàng)建了一個(gè)數(shù)字集合,接下來(lái)使用 stream() 方法轉(zhuǎn)化為 Stream 流
使用 distinct() 方法對(duì)流中的元素進(jìn)行去重,返回一個(gè)不包含重復(fù)元素的Stream 流
最后使用 collect() 方法對(duì)去重后的流轉(zhuǎn)換成一個(gè)新的 List 集合。
2.6 limit(long n)
用于限制Stream的大小,返回一個(gè)最大包含前n個(gè)元素的新Stream。
示例:
public class LimitStreamTest {
public static void main(String[] args) {
List<Integer> numList = Arrays.asList(1,2,3,4,5,6,7,8);
List<Integer> limitList = numList.stream()
.limit(4)
.collect(Collectors.toList());
System.out.println(limitList);
}
}
這段代碼創(chuàng)建一個(gè)包含整數(shù)的List集合numList
,使用Stream API的limit(4)
方法將集合截取為只包含前4個(gè)元素的新List集合,并將結(jié)果輸出到控制臺(tái)。
輸出結(jié)果為:[1, 2, 3, 4]
2.7 skip(long n)
用于跳過(guò)Stream中的前n個(gè)元素,返回一個(gè)丟棄了前n個(gè)元素后剩余元素的新Stream。
示例:
public class SkipStreamTest {
public static void main(String[] args) {
List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
List<Integer> skipList = numList.stream()
.skip(numList.size() - 2)
.collect(Collectors.toList());
System.out.println(skipList);
}
}
這段代碼創(chuàng)建一個(gè)包含整數(shù)的List集合numList
,使用Stream API的 skip
方法將集合截取跳過(guò)前 集合大小-2
個(gè)元素的新List集合,并將結(jié)果輸出到控制臺(tái)。
輸出結(jié)果為:[7, 8]
2.8 peek(Consumer)
用于對(duì)每個(gè)元素執(zhí)行一個(gè)操作,同時(shí)保持Stream的流。它可以用于調(diào)試或記錄Stream中的元素。
示例:
public class PeekStreamTest {
public static void main(String[] args) {
List<Integer> numList = Arrays.asList(5, 6, 7, 8);
List<Integer> resList = numList.stream()
.peek(System.out::println)
.filter(s -> s == 5)
.peek(s -> System.out.printf("過(guò)濾后的:%d%n", s))
.collect(Collectors.toList());
}
}
輸出:
5
過(guò)濾后的:5
6
7
8
這段代碼創(chuàng)建一個(gè)包含整數(shù)的List集合numList
,使用Stream API的 peek
方法記錄初始的值,通過(guò)中間操作 filter 方法過(guò)濾值為 5 的后,再次通過(guò)peek 方法來(lái)打印并驗(yàn)證我們的表達(dá)式后,把過(guò)濾后的結(jié)果通過(guò) collect 方法生成一個(gè)新的 List 集合。
3.終端操作
在Java Stream API中,終端操作(Terminal Operations)是對(duì)Stream進(jìn)行最終處理的操作。當(dāng)調(diào)用終端操作時(shí),Stream會(huì)開(kāi)始執(zhí)行中間操作,并生成最終的結(jié)果或副作用。終端操作是Stream的觸發(fā)器
,一旦調(diào)用終端操作,Stream就不能再被使用,也不能再進(jìn)行中間操作。
以下是一些常見(jiàn)的Stream API終端操作:
3.1 forEach(Consumer)
對(duì)Stream中的每個(gè)元素執(zhí)行指定的操作,接收一個(gè)Consumer(消費(fèi)者函數(shù))作為參數(shù)。它通常用于對(duì)Stream中的元素進(jìn)行輸出或執(zhí)行某些操作,但不會(huì)返回任何結(jié)果。
示例: 遍歷輸出中間操作后的集合
public class ForEachStreamTest {
public static void main(String[] args) {
// 給公司工資普漲 500
List<Integer> salaryList = Arrays.asList(12000, 20000, 30000, 4000);
salaryList.stream()
.peek(s -> System.out.print("工資普漲前:" + s))
.map(s -> s + 500)
.forEach(s -> {
System.out.println("--工資普漲后:" + s);
});
}
}
以上代碼的含義是,創(chuàng)建一個(gè)工資集合,通過(guò) stream() 方法轉(zhuǎn)換為 Stream 流,通過(guò)中間操作 peek() 方法記錄轉(zhuǎn)換前的元素值,后通過(guò) map() 方法給元素進(jìn)行轉(zhuǎn)換操作,最后通過(guò)終端操作 forEach() 方法進(jìn)行遍歷.
輸出:
工資普漲前:12000--工資普漲后:12500
工資普漲前:20000--工資普漲后:20500
工資普漲前:30000--工資普漲后:30500
工資普漲前:4000--工資普漲后:4500
3.2 collect(Collector)
用于將Stream中的元素收集到一個(gè)容器中,接收一個(gè)Collector(收集器)作為參數(shù)。它允許你在Stream中執(zhí)行各種集合操作,例如將元素收集到List、Set、Map等容器中。
示例: 把 User 實(shí)體集合轉(zhuǎn)換為 Map 集合,名字作為 key,工資作為 Name
public class CollectStreamTest {
public static void main(String[] args) {
List<User> userList = Arrays.asList(new User("張三", 2000.5),
new User("李斯", 11000.5),
new User("王二", 12000.5),
new User("張六", 32000.5),
new User("趙公子", 1000000.0));
Map<String, Double> userSalaryMap = userList.stream()
.collect(Collectors.toMap(User::getName, User::getSalary));
userSalaryMap.forEach((k, v) -> {
System.out.printf("姓名:%s,工資:%.2f%n", k, v);
});
}
@Data
@AllArgsConstructor
static class User {
private String name;
private Double salary;
}
}
上述代碼的含義是創(chuàng)建一個(gè)人員集合,通過(guò) stream() 轉(zhuǎn)換為 Stream 流,使用 collect() 方法把元素歸集, 利用 Collectors.toMap() 收集器轉(zhuǎn)換為 Map 后,內(nèi)部接收會(huì)遍歷每個(gè)元素,
Collectors.toMap(User::getName, User::getSalary)
是簡(jiǎn)寫(xiě),詳細(xì)的寫(xiě)法如下:Collectors.toMap(s -> s.getName(), s -> s.getSalary())
輸出:
姓名:張三,工資:2000.50
姓名:趙公子,工資:1000000.00
姓名:張六,工資:32000.50
姓名:李斯,工資:11000.50
姓名:王二,工資:12000.50
3.3 toArray()
將Stream中的元素轉(zhuǎn)換成一個(gè)數(shù)組。返回一個(gè)包含所有元素的數(shù)組,返回的數(shù)組類(lèi)型是根據(jù)流元素的類(lèi)型自動(dòng)推斷的。如果流是空的,將返回一個(gè)長(zhǎng)度為0的數(shù)組。
示例:
public class ToArrayStreamTest {
public static void main(String[] args) {
// 示例整數(shù)流
IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
// 使用toArray()將流中的元素收集到一個(gè)數(shù)組中
int[] intArray = intStream.toArray();
// 輸出結(jié)果數(shù)組
System.out.println(Arrays.toString(intArray));
}
}
輸出:
[1, 2, 3, 4, 5]
在這個(gè)示例中,我們創(chuàng)建了一個(gè)整數(shù)流
IntStream
,然后使用toArray()
方法將流中的所有整數(shù)收集到一個(gè)數(shù)組中,并輸出結(jié)果數(shù)組。
3.4 reduce(BinaryOperator)
Stream
類(lèi)的 reduce()
方法是用于將流中的元素進(jìn)行歸約操作的方法。接收一個(gè) BinaryOperator(二元運(yùn)算函數(shù)
作為參數(shù),用于對(duì)兩個(gè)元素進(jìn)行操作,并返回一個(gè)合并后的結(jié)果。它可以將流中的所有元素按照指定的規(guī)則進(jìn)行合并,并返回一個(gè) Optional
對(duì)象,因?yàn)榱骺赡転榭铡?/p>
示例:
public class ReduceStreamTest {
public static void main(String[] args) {
// 示例整數(shù)流
IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
// 使用reduce()將流中的整數(shù)相加得到總和
OptionalInt sumOptional = intStream.reduce((a, b) -> a + b);
// 獲取結(jié)果總和,如果流為空,則給出一個(gè)默認(rèn)值0
int sum = sumOptional.orElse(0);
// 輸出結(jié)果總和
System.out.println("總和: " + sum);
}
}
輸出:
總和: 15
上面的代碼中,我們創(chuàng)建了一個(gè)整數(shù)流
IntStream
,然后使用reduce()
方法將流中的整數(shù)相加得到總和。由于流中有元素,因此reduce()
方法返回包含總和的Optional
對(duì)象。我們使用orElse(0)
獲取結(jié)果總和,防止流為空的情況。最后輸出得到的結(jié)果總和。
3.5 min(Comparator) / max(Comparator)
Stream
類(lèi)的 min()
和 max()
方法是用于查找流中的最小值和最大值的終端操作。它們接受一個(gè) Comparator
對(duì)象作為參數(shù)來(lái)確定元素的順序,并返回一個(gè) Optional
對(duì)象,因?yàn)榱骺赡転榭铡?/p>
以下是 min()
和 max()
方法的簡(jiǎn)要解釋以及示例代碼:
min()
方法:
Optional<T> min(Comparator<? super T> comparator)
- 方法簽名:
<T> Optional<T> min(Comparator<? super T> comparator)
-
min()
方法用于查找流中的最小元素。 -
comparator
參數(shù)用于確定元素的順序,以便找到最小值。 - 如果流為空,則返回一個(gè)空的
Optional
對(duì)象。
max()
方法:
Optional<T> max(Comparator<? super T> comparator)
- 方法簽名:
<T> Optional<T> max(Comparator<? super T> comparator)
-
max()
方法用于查找流中的最大元素。 -
comparator
參數(shù)用于確定元素的順序,以便找到最大值。 - 如果流為空,則返回一個(gè)空的
Optional
對(duì)象。
示例:假設(shè)我們有一個(gè)包含整數(shù)的流,并且我們想找到其中的最小值和最大值
public class MinMaxStreamTest {
public static void main(String[] args) {
// 示例整數(shù)流
Stream<Integer> integerStream = Stream.of(1, 5, 3, 8, 2);
// 使用min()找到最小值
Optional<Integer> minOptional = integerStream.min(Integer::compareTo);
if (minOptional.isPresent()) {
System.out.println("最小值為: " + minOptional.get());
} else {
System.out.println("流為空.");
}
// 重新創(chuàng)建一個(gè)整數(shù)流,因?yàn)榱饕驯幌?/span>
Stream<Integer> newIntegerStream = Stream.of(1, 5, 3, 8, 2);
// 使用max()找到最大值
Optional<Integer> maxOptional = newIntegerStream.max(Integer::compareTo);
if (maxOptional.isPresent()) {
System.out.println("最大值為: " + maxOptional.get());
} else {
System.out.println("流為空.");
}
}
}
輸出:
最小值為: 1
最大值為: 8
上述代碼中,我們創(chuàng)建了一個(gè)整數(shù)流
Stream<Integer>
,然后使用min()
方法找到最小值,并使用max()
方法找到最大值。我們使用Optional
對(duì)象來(lái)處理可能為空的情況,并輸出找到的最小值和最大值。請(qǐng)注意,一旦流被消耗,就不能再次使用它,因此我們?cè)谡业阶钚≈岛笾匦聞?chuàng)建了一個(gè)整數(shù)流來(lái)找到最大值。
3.6 count()
Stream
類(lèi)的 count()
方法是用于計(jì)算流中元素個(gè)數(shù)的終端操作。它返回一個(gè) long
類(lèi)型的值,表示流中的元素?cái)?shù)量。count()
方法是一個(gè)終端操作,一旦調(diào)用該方法,流就被消耗,無(wú)法再次使用。
示例: 有一個(gè)包含整數(shù)的流,并且我們想計(jì)算流中的元素個(gè)數(shù)
public class CountStreamTest {
public static void main(String[] args) {
// 示例整數(shù)流
Stream<Integer> integerStream = Stream.of(1, 5, 3, 8, 2);
// 使用count()計(jì)算流中的元素個(gè)數(shù)
long count = integerStream.count();
// 輸出元素個(gè)數(shù)
System.out.println("元素?cái)?shù)量: " + count);
}
}
輸出:
元素?cái)?shù)量: 5
上述代碼中,我們創(chuàng)建了一個(gè)整數(shù)流
Stream<Integer>
,然后使用count()
方法計(jì)算流中的元素個(gè)數(shù)。由于這是一個(gè)終端操作,一旦調(diào)用了count()
方法,流就會(huì)被消耗,不能再次使用。我們輸出計(jì)算得到的元素個(gè)數(shù)。
3.7 anyMatch(Predicate) / allMatch(Predicate) / noneMatch(Predicate)
Stream
類(lèi)的 anyMatch()
, allMatch()
, 和 noneMatch()
是用于檢查流中元素是否滿足特定條件的終端操作。它們返回一個(gè)布爾值,表示流中的元素是否滿足指定的條件。這些方法在遇到滿足條件的元素后可能會(huì)提前終止流的處理。anyMatch檢查是否有任意元素滿足條件,allMatch檢查是否所有元素都滿足條件,noneMatch檢查是否沒(méi)有元素滿足條件。
以下是 anyMatch()
, allMatch()
, 和 noneMatch()
方法的簡(jiǎn)要解釋以及示例代碼:
anyMatch()
方法:
boolean anyMatch(Predicate<? super T> predicate)
- 方法簽名:
boolean anyMatch(Predicate<? super T> predicate)
-
anyMatch()
方法用于檢查流中是否存在至少一個(gè)元素滿足給定的條件。 - 它接受一個(gè)
Predicate
參數(shù),用于定義滿足條件的判斷規(guī)則。 - 如果流中至少有一個(gè)元素滿足條件,返回
true
,否則返回false
。
allMatch()
方法:
boolean allMatch(Predicate<? super T> predicate)
- 方法簽名:
boolean allMatch(Predicate<? super T> predicate)
-
allMatch()
方法用于檢查流中的所有元素是否都滿足給定的條件。 - 它接受一個(gè)
Predicate
參數(shù),用于定義滿足條件的判斷規(guī)則。 - 如果流中的所有元素都滿足條件,返回
true
,否則返回false
。
noneMatch()
方法:
boolean noneMatch(Predicate<? super T> predicate)
- 方法簽名:
boolean noneMatch(Predicate<? super T> predicate)
-
noneMatch()
方法用于檢查流中是否所有元素都不滿足給定的條件。 - 它接受一個(gè)
Predicate
參數(shù),用于定義滿足條件的判斷規(guī)則。 - 如果流中的所有元素都不滿足條件,返回
true
,否則返回false
。
示例代碼:
假設(shè)我們有一個(gè)包含整數(shù)的流,并且我們想檢查流中是否存在某些元素滿足特定條件。
public class MatchStreamTest {
public static void main(String[] args) {
// 示例整數(shù)流
Stream<Integer> integerStream = Stream.of(1, 5, 3, 8, 2);
// 使用anyMatch()檢查是否存在元素大于5
boolean anyGreaterThan5 = integerStream.anyMatch(num -> num > 4);
System.out.println("是否存在元素大于 5 ?" + anyGreaterThan5);
// 重新創(chuàng)建一個(gè)整數(shù)流,因?yàn)榱饕驯幌?/span>
Stream<Integer> newIntegerStream = Stream.of(1, 5, 3, 8, 2);
// 使用allMatch()檢查是否所有元素都小于10
boolean allLessThan10 = newIntegerStream.allMatch(num -> num < 10);
System.out.println("所有元素都小于10 ? " + allLessThan10);
// 重新創(chuàng)建一個(gè)整數(shù)流,因?yàn)榱饕驯幌?/span>
Stream<Integer> newestIntegerStream = Stream.of(1, 5, 3, 8, 2);
// 使用noneMatch()檢查是否沒(méi)有元素等于10
boolean noneEqualTo10 = newestIntegerStream.noneMatch(num -> num == 10);
System.out.println("是否沒(méi)有元素等于 10 ? " + noneEqualTo10);
}
}
輸出:
是否存在元素大于 5 ?true
所有元素都小于10? true
是否沒(méi)有元素等于 10 ? true
上述代碼中,我們創(chuàng)建了一個(gè)整數(shù)流
Stream<Integer>
,然后使用anyMatch()
方法檢查是否存在元素大于5,使用allMatch()
方法檢查是否所有元素都小于10,以及使用noneMatch()
方法檢查是否沒(méi)有元素等于10。我們輸出檢查的結(jié)果。注意,在每次使用終端操作后,流就被消耗了,不能再次使用,因此在檢查不同條件時(shí)需要重新創(chuàng)建流。
3.8 findFirst() / findAny()
Stream
類(lèi)的 findFirst()
和 findAny()
方法用于在流中查找元素的終端操作。它們都返回一個(gè) Optional
對(duì)象,表示找到的元素或元素的可能性。在并行流中,findAny()
方法可能更快,因?yàn)樗灰欢ㄒ闅v所有元素。在串行 Stream
中,findFirst()
和 findAny()
返回的是相同的元素,在并行Stream
中,findAny()
返回的是最先找到的元素。
以下是 findFirst()
和 findAny()
方法的簡(jiǎn)要解釋以及示例代碼:
findFirst()
方法:
Optional<T> findFirst()
- 方法簽名:
Optional<T> findFirst()
-
findFirst()
方法用于在流中查找第一個(gè)滿足條件的元素。 - 它返回一個(gè)
Optional
對(duì)象,表示找到的元素,如果流為空,則返回一個(gè)空的Optional
對(duì)象。
findAny()
方法:
Optional<T> findAny()
- 方法簽名:
Optional<T> findAny()
-
findAny()
方法用于在流中查找任意一個(gè)滿足條件的元素。 - 它返回一個(gè)
Optional
對(duì)象,表示找到的元素,如果流為空,則返回一個(gè)空的Optional
對(duì)象。 - 在并行流中,
findAny()
方法可能比findFirst()
方法更快,因?yàn)樗灰欢ㄒ闅v所有元素。
示例代碼:
假設(shè)我們有一個(gè)包含整數(shù)的流,并且我們想查找其中的某個(gè)元素。
public class FindStreamTest {
public static void main(String[] args) {
// 示例整數(shù)流
Stream<Integer> integerStream = Stream.of(1, 5, 3, 8, 2);
// 使用findFirst()找到第一個(gè)元素
Optional<Integer> firstElementOptional = integerStream.findFirst();
if (firstElementOptional.isPresent()) {
System.out.println("發(fā)現(xiàn)第一個(gè)元素: " + firstElementOptional.get());
} else {
System.out.println("流為空!");
}
// 重新創(chuàng)建一個(gè)整數(shù)流,因?yàn)榱饕驯幌?/span>
Stream<Integer> newIntegerStream = Stream.of(1, 5, 3, 8, 2);
// 使用findAny()找到任意一個(gè)元素
Optional<Integer> anyElementOptional = newIntegerStream.findAny();
if (anyElementOptional.isPresent()) {
System.out.println("找到任意一個(gè)元素: " + anyElementOptional.get());
} else {
System.out.println("流為空!");
}
}
}
輸出(注意輸出的結(jié)果可能因?yàn)榱鞯奶幚眄樞虿煌兴兓?mark hidden color="red">文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-714761.html
發(fā)現(xiàn)第一個(gè)元素: 1
找到任意一個(gè)元素: 1
上述代碼中,創(chuàng)建了整數(shù)流
Stream<Integer>
,然后使用findFirst()
方法找到第一個(gè)元素,使用findAny()
方法找到任意一個(gè)元素,并輸出找到的元素。請(qǐng)注意,一旦調(diào)用了這些方法,流就被消耗了,不能再次使用。在并行流中,findAny()
方法可能比findFirst()
方法更快,因?yàn)樗灰欢ㄒ闅v所有元素。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-714761.html
到了這里,關(guān)于Java Stream 常用方法【詳盡篇】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!