做時時彩開獎網(wǎng)站犯法嗎aso關(guān)鍵詞優(yōu)化工具
![]()
🏷?個人主頁:牽著貓散步的鼠鼠?
🏷?系列專欄:Java全棧-專欄
🏷?個人學(xué)習(xí)筆記,若有缺誤,歡迎評論區(qū)指正?
前些天發(fā)現(xiàn)了一個巨牛的人工智能學(xué)習(xí)網(wǎng)站,通俗易懂,風(fēng)趣幽默,忍不住分享一下給大家。點擊跳轉(zhuǎn)到網(wǎng)站AI學(xué)習(xí)網(wǎng)站。??
目錄
前言
Stream API的三個階段
創(chuàng)建Stream流
Stream API中間操作
filter
map
flatMap
distinct
sorted
peek
limit 和 skip
Stream API終端操作
forEach
toArray
reduce
collect
count
anyMatch、allMatch 和 noneMatch
findAny 和 findFirst
min 和 max
注意事項
總結(jié)
前言
Java8中有兩大最為重要的改變。第一個是 Lambda 表達式;另外一個則是 Stream API。
Stream 是 Java8 中處理集合的關(guān)鍵抽象概念,它可以指定你希望對集合進行的操作,可以執(zhí)行非常復(fù)雜的查找、過濾和映射數(shù)據(jù)等操作。使用Stream API 對集合數(shù)據(jù)進行操作,就類似于使用 SQL 執(zhí)行的數(shù)據(jù)庫查詢。也可以使用 Stream API 來并行執(zhí)行操作。簡而言之,Stream API 提供了一種高效且易于使用的處理數(shù)據(jù)的方式
流是數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(集合、數(shù)組等)所生成的元素序列。“集合講的是數(shù)據(jù),流講的是計算!”
注意:
① Stream 自己不會存儲元素。
② Stream 不會改變源對象。相反,他們會返回一個持有結(jié)果的新Stream。
③ Stream 操作是延遲執(zhí)行的。這意味著他們會等到需要結(jié)果的時候才執(zhí)行。
Stream API的三個階段
在Java中,Stream 是Java 8引入的一個新概念,用于處理集合(Collections)數(shù)據(jù)的一種抽象。Java的Stream API 提供了一種聲明式的方式來操作數(shù)據(jù)集合,可以用更簡潔、可讀性更強的代碼來進行集合的操作。
Java Stream API的操作可以分為三個階段:
1. 創(chuàng)建流(Creation of Stream):?這個階段涉及到從不同的數(shù)據(jù)源創(chuàng)建流,可以是集合、數(shù)組、I/O通道等。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream();
2. 中間操作(Intermediate Operations):?這個階段包括對流的轉(zhuǎn)換操作,可以對流進行過濾、映射、排序等操作。這些操作并不會改變原始數(shù)據(jù)源,而是返回一個新的流。
Stream<Integer> filteredStream = stream.filter(x -> x > 2);
3. 終端操作(Terminal Operations):?這個階段是對流進行最終操作,觸發(fā)流的遍歷,可以產(chǎn)生一個結(jié)果或者副作用。終端操作是流的最后一個操作,執(zhí)行后流將不可再用。
long count = filteredStream.count();
這三個階段的設(shè)計使得可以通過鏈?zhǔn)秸{(diào)用的方式組合多個操作,從而編寫更為清晰和簡潔的代碼。這種方式也有助于提高代碼的可讀性和可維護性。
當(dāng)然,這里只是對于Stream API三個階段的概述,只是告訴大家,簡單分為三個階段,至于三個階段里面有哪些主要的方法,我們在下文進行詳細敘述,這里我們點到為止!現(xiàn)在,大家心里面就應(yīng)該有這么一個藍圖,或者是基本框架,知道我們接下來將會沿著那個幾個方向展開敘述!
創(chuàng)建Stream流
在Java中,你可以使用多種方式來創(chuàng)建Stream流。
從集合創(chuàng)建:
使用集合類的 stream() 或 parallelStream() 方法可以創(chuàng)建對應(yīng)的流。例如:
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> streamFromList = list.stream();
從數(shù)組創(chuàng)建:
使用 Arrays.stream() 方法可以從數(shù)組中創(chuàng)建流:
String[] array = {"apple", "banana", "orange"};
Stream<String> streamFromArray = Arrays.stream(array);
通過Stream的靜態(tài)方法創(chuàng)建:
Stream 類提供了靜態(tài)方法 of(),可以傳入一系列元素來創(chuàng)建流:
Stream<String> stream = Stream.of("apple", "banana", "orange");
使用Stream的generate和iterate方法:
Stream 類還提供了 generate 和 iterate 方法,用于生成無限流:
// 生成包含隨機整數(shù)的無限流
Stream<Integer> infiniteStream = Stream.generate(() -> (int) (Math.random() * 100));// 從指定的起始值開始,按照某個規(guī)則生成無限流
Stream<Integer> sequentialStream = Stream.iterate(1, n -> n + 1);
通過文件生成流:
java.nio.file.Files 類提供了靜態(tài)方法 lines(),可以用來讀取文件內(nèi)容并生成流:
Path path = Paths.get("example.txt");
Stream<String> fileLines = Files.lines(path);
使用正則表達式生成流:
Pattern 類的 splitAsStream 方法可以根據(jù)正則表達式將字符串分割成流:
String text = "apple,orange,banana";
Stream<String> textStream = Pattern.compile(",").splitAsStream(text);
Stream API中間操作
Stream API 提供了許多中間操作,用于對流進行轉(zhuǎn)換、篩選和處理。
filter
用于篩選元素,根據(jù)指定的條件保留符合條件的元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> filteredStream = numbers.stream().filter(x -> x > 2);
map
對流中的每個元素應(yīng)用指定的函數(shù),并將結(jié)果映射為一個新的元素。
List<String> words = Arrays.asList("apple", "banana", "orange");
Stream<Integer> wordLengths = words.stream().map(String::length);
flatMap
將流中的每個元素都轉(zhuǎn)換為一個流,然后將這些流連接起來成為一個流。
List<List<Integer>> numbers = Arrays.asList(Arrays.asList(1, 2),Arrays.asList(3, 4),Arrays.asList(5, 6)
);Stream<Integer> flatStream = numbers.stream().flatMap(List::stream);
distinct
去除流中的重復(fù)元素。
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
Stream<Integer> distinctNumbers = numbers.stream().distinct();
sorted
對流中的元素進行排序。
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
Stream<Integer> sortedNumbers = numbers.stream().sorted();
peek
對流中的每個元素執(zhí)行操作,主要用于調(diào)試和觀察流中的元素。
List<String> words = Arrays.asList("apple", "banana", "orange");
Stream<String> peekStream = words.stream().peek(System.out::println);
limit 和 skip
limit 用于截斷流,保留指定數(shù)量的元素,而 skip 則用于跳過指定數(shù)量的元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> limitedStream = numbers.stream().limit(3);
Stream<Integer> skippedStream = numbers.stream().skip(2);
Stream API終端操作
Stream API 的終端操作用于觸發(fā)對流的最終操作,產(chǎn)生結(jié)果或者引起副作用。
forEach
對流中的每個元素執(zhí)行指定的操作。
List<String> words = Arrays.asList("apple", "banana", "orange");
words.stream().forEach(System.out::println);
toArray
將流中的元素轉(zhuǎn)換為數(shù)組。
List<String> words = Arrays.asList("apple", "banana", "orange");
String[] wordArray = words.stream().toArray(String[]::new);
reduce
對流中的元素進行歸約操作,可以用于求和、求最大值、最小值等。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = numbers.stream().reduce(Integer::sum);
collect
將流中的元素收集到一個集合中,例如 List、Set 或 Map。
List<String> words = Arrays.asList("apple", "banana", "orange");
List<String> collectedWords = words.stream().collect(Collectors.toList());
count
返回流中的元素數(shù)量。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream().count();
anyMatch、allMatch 和 noneMatch
用于檢查流中是否存在滿足指定條件的元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean anyGreaterThanThree = numbers.stream().anyMatch(x -> x > 3);
boolean allGreaterThanTwo = numbers.stream().allMatch(x -> x > 2);
boolean noneGreaterThanFive = numbers.stream().noneMatch(x -> x > 5);
findAny 和 findFirst
返回流中的任意一個元素或者第一個元素。
List<String> words = Arrays.asList("apple", "banana", "orange");
Optional<String> anyWord = words.stream().findAny();
Optional<String> firstWord = words.stream().findFirst();
min 和 max
返回流中的最小值或最大值。
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
Optional<Integer> minNumber = numbers.stream().min(Integer::compare);
Optional<Integer> maxNumber = numbers.stream().max(Integer::compare);
注意事項
使用Stream API時,有一些需要注意的重要事項,以確保正確、高效地利用這一功能:
只能使用一次: 一個 Stream 實例只能被消費(執(zhí)行終端操作)一次。如果你嘗試對已經(jīng)使用過的流進行其他終端操作,會拋出 IllegalStateException 異常。如果需要再次操作,可以重新創(chuàng)建一個新的流。
List<String> words = Arrays.asList("apple", "banana", "orange");
Stream<String> wordStream = words.stream();// 正確的做法
long count = wordStream.count();// 錯誤的做法,會拋出IllegalStateException
long anotherCount = wordStream.count();
及早退出: 在處理大量數(shù)據(jù)時,及早退出可以提高性能。使用 anyMatch()、findFirst() 等終端操作時,一旦找到符合條件的元素,就會立即返回,不再繼續(xù)處理后續(xù)元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean anyGreaterThanThree = numbers.stream().anyMatch(x -> {System.out.println("Checking: " + x);return x > 3;
});
并行流的謹(jǐn)慎使用: Stream API 提供了并行流的支持,可以通過 parallel() 方法將順序流轉(zhuǎn)換為并行流。但并不是所有的場景都適合使用并行流,因為在某些情況下,并行流可能會導(dǎo)致性能下降,甚至出現(xiàn)并發(fā)問題。在并行流的使用上需要注意線程安全等問題。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.parallelStream().filter(x -> x > 2).count();
使用適當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu):?在創(chuàng)建流時,選擇適當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu)能夠影響流操作的性能。例如,ArrayList 在順序訪問時性能較好,而 LinkedList 在隨機訪問時性能較好。
總結(jié)
總體而言,了解Stream API的使用原則,結(jié)合具體的業(yè)務(wù)場景和性能需求,能夠更好地利用Stream API完成任務(wù)。注意流的延遲計算特性,避免副作用,可以使代碼更加清晰、可讀,并提高代碼的可維護性。