java構(gòu)建Stream流的多種方式總結(jié)
Java 8引入了Stream流作為一項(xiàng)新的特性,它是用來處理集合數(shù)據(jù)的一種函數(shù)式編程方式。Stream流提供了一種更簡(jiǎn)潔、高效和易于理解的方法來操作集合數(shù)據(jù),同時(shí)也能夠?qū)崿F(xiàn)并行處理,以提高性能。
以下是Stream流的一些重要特征和用法:
- 流的創(chuàng)建:可以從集合、數(shù)組、I/O通道等多種數(shù)據(jù)源創(chuàng)建Stream流。例如,使用
Collection.stream()
方法可以將集合轉(zhuǎn)換為流,使用Arrays.stream()
可以將數(shù)組轉(zhuǎn)換為流。 - 中間操作:Stream流支持各種中間操作,這些操作允許對(duì)流中的元素進(jìn)行過濾、映射、排序等操作,而不會(huì)修改原始數(shù)據(jù)。一些常見的中間操作包括
filter
(過濾元素)、map
(映射元素)、sorted
(排序元素)等。 - 終端操作:終端操作是對(duì)流進(jìn)行最終操作,它們觸發(fā)實(shí)際的計(jì)算并生成結(jié)果。一些常見的終端操作包括
forEach
(遍歷元素并執(zhí)行操作)、collect
(將流中的元素收集到一個(gè)集合中)、count
(計(jì)算元素個(gè)數(shù))等。 - 延遲執(zhí)行:Stream操作是延遲執(zhí)行的,這意味著中間操作可以在不實(shí)際計(jì)算的情況下鏈接在一起。只有在調(diào)用終端操作時(shí),才會(huì)觸發(fā)流的處理。
- 并行處理:Stream流支持并行處理,通過使用
parallelStream()
方法,可以輕松地將流的處理分布到多個(gè)處理器核心上,以提高性能。 - 函數(shù)式編程風(fēng)格:Stream流鼓勵(lì)使用函數(shù)式編程風(fēng)格,其中操作是以lambda表達(dá)式的形式傳遞的,使代碼更具表達(dá)力和簡(jiǎn)潔。
以下是一個(gè)示例,演示了如何使用Stream流來操作一個(gè)集合:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); int sum = numbers.stream() .filter(n -> n % 2 == 0) // 過濾偶數(shù) .map(n -> n * 2) // 將偶數(shù)翻倍 .reduce(0, Integer::sum); // 求和 System.out.println("偶數(shù)的翻倍之和為: " + sum);
這只是Stream流的一個(gè)簡(jiǎn)單示例,它展示了Stream流的一些常見操作,如過濾、映射和匯總。通過Stream流,可以以更簡(jiǎn)潔和可讀的方式處理集合數(shù)據(jù),減少了樣板代碼,提高了代碼質(zhì)量和可維護(hù)性。下面我們將對(duì)構(gòu)建流的多種方式多種方式展開做一個(gè)詳細(xì)闡述。
1.從集合創(chuàng)建流
從集合創(chuàng)建Stream流非常簡(jiǎn)單,可以使用集合類的stream()
方法來獲取一個(gè)Stream對(duì)象。下面我將展示如何從集合創(chuàng)建Stream,并結(jié)合實(shí)際應(yīng)用提供兩個(gè)代碼示例。
示例1:從List創(chuàng)建Stream
import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; public class StreamCreationExample { public static void main(String[] args) { List<String> names = new ArrayList<>(); names.add("Alice"); names.add("Bob"); names.add("Charlie"); names.add("David"); names.add("Eve"); // 創(chuàng)建一個(gè)Stream流 Stream<String> nameStream = names.stream(); // 使用Stream流進(jìn)行操作 nameStream .filter(name -> name.startsWith("A")) .forEach(System.out::println); } }
這個(gè)示例中,我們首先創(chuàng)建了一個(gè)包含一些姓名的List集合,然后使用names.stream()
方法創(chuàng)建了一個(gè)Stream流。接著,我們使用filter
中間操作篩選出以"A"開頭的姓名,并使用forEach
終端操作打印輸出結(jié)果。
示例2:從Map創(chuàng)建Stream
import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; public class StreamCreationFromMapExample { public static void main(String[] args) { Map<Integer, String> studentMap = new HashMap<>(); studentMap.put(1, "Alice"); studentMap.put(2, "Bob"); studentMap.put(3, "Charlie"); studentMap.put(4, "David"); studentMap.put(5, "Eve"); // 從Map的鍵集合創(chuàng)建Stream Stream<Integer> studentIdsStream = studentMap.keySet().stream(); // 使用Stream流進(jìn)行操作 studentIdsStream .filter(id -> id % 2 == 0) .forEach(id -> System.out.println(id + ": " + studentMap.get(id))); } }
這個(gè)示例中,我們創(chuàng)建了一個(gè)包含學(xué)生ID和姓名的Map,然后使用studentMap.keySet().stream()
方法從Map的鍵集合創(chuàng)建了一個(gè)Stream流。接著,我們使用filter
中間操作篩選出偶數(shù)的學(xué)生ID,并使用forEach
終端操作打印出相應(yīng)的學(xué)生信息。
2.從數(shù)組創(chuàng)建流
從數(shù)組創(chuàng)建Stream流也非常簡(jiǎn)單,Java 8 提供了Arrays.stream()
方法,它允許將一個(gè)數(shù)組轉(zhuǎn)換為一個(gè)Stream流。下面我將詳細(xì)介紹如何從數(shù)組創(chuàng)建Stream,并提供兩個(gè)代碼示例。
示例1:從整數(shù)數(shù)組創(chuàng)建Stream
import java.util.Arrays; import java.util.stream.IntStream; public class StreamCreationFromArrayExample { public static void main(String[] args) { int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 從整數(shù)數(shù)組創(chuàng)建IntStream IntStream numberStream = Arrays.stream(numbers); // 使用Stream流進(jìn)行操作 int sum = numberStream .filter(n -> n % 2 == 0) .map(n -> n * 2) .sum(); System.out.println("偶數(shù)的翻倍之和為: " + sum); } }
在這個(gè)示例中,我們首先創(chuàng)建了一個(gè)整數(shù)數(shù)組 numbers
,然后使用 Arrays.stream(numbers)
方法將它轉(zhuǎn)換為一個(gè) IntStream
流。接著,我們使用該流進(jìn)行一系列操作,包括篩選出偶數(shù)并將其翻倍,最后計(jì)算它們的總和。
示例2:從字符串?dāng)?shù)組創(chuàng)建Stream
import java.util.Arrays; import java.util.stream.Stream; public class StreamCreationFromArrayExample { public static void main(String[] args) { String[] words = {"apple", "banana", "cherry", "date", "elderberry"}; // 從字符串?dāng)?shù)組創(chuàng)建Stream Stream<String> wordStream = Arrays.stream(words); // 使用Stream流進(jìn)行操作 wordStream .filter(word -> word.startsWith("b")) .map(String::toUpperCase) .forEach(System.out::println); } }
在這個(gè)示例中,我們創(chuàng)建了一個(gè)字符串?dāng)?shù)組 words
,然后使用 Arrays.stream(words)
方法將它轉(zhuǎn)換為一個(gè) Stream
流。接著,我們使用流進(jìn)行操作,包括篩選出以字母 "b" 開頭的單詞,并將它們轉(zhuǎn)換為大寫形式后打印輸出。
3.靜態(tài)工廠方法
Java 8也引入了一些靜態(tài)工廠方法來創(chuàng)建Stream流,這些方法使得創(chuàng)建Stream流變得更加簡(jiǎn)便和靈活。下面我將詳細(xì)介紹這些靜態(tài)工廠方法,并提供兩個(gè)代碼示例。
靜態(tài)工廠方法創(chuàng)建Stream
Stream.of(T... values)
:通過將一個(gè)可變參數(shù)的元素列表傳遞給Stream.of
方法來創(chuàng)建一個(gè)包含這些元素的Stream流。這對(duì)于創(chuàng)建具有少量元素的流非常方便。Stream.empty()
:使用Stream.empty()
方法創(chuàng)建一個(gè)空的Stream流。Stream.generate(Supplier<T> s)
:通過提供一個(gè)Supplier
函數(shù)來創(chuàng)建一個(gè)無限大小的Stream流,該函數(shù)會(huì)生成元素。通常,需要使用limit
操作限制生成的元素?cái)?shù)量。Stream.iterate(T seed, UnaryOperator<T> f)
:通過提供初始值(seed)和一個(gè)一元操作函數(shù)(UnaryOperator)來創(chuàng)建一個(gè)包含無限序列的Stream流。例如,可以使用Stream.iterate(0, n -> n + 1)
來創(chuàng)建一個(gè)自然數(shù)序列的Stream流。
示例1:使用Stream.of創(chuàng)建Stream
import java.util.stream.Stream; public class StreamFactoryExample { public static void main(String[] args) { // 使用Stream.of創(chuàng)建Stream流 Stream<String> stream = Stream.of("Apple", "Banana", "Cherry", "Date"); // 打印Stream中的元素 stream.forEach(System.out::println); } }
這個(gè)示例使用Stream.of
靜態(tài)工廠方法創(chuàng)建了一個(gè)包含水果名稱的Stream流,并使用forEach
終端操作打印出每個(gè)水果的名稱。
示例2:使用Stream.generate創(chuàng)建Stream
import java.util.Random; import java.util.stream.Stream; public class StreamGenerateExample { public static void main(String[] args) { // 使用Stream.generate創(chuàng)建隨機(jī)整數(shù)流 Stream<Integer> randomIntStream = Stream.generate(() -> new Random().nextInt(100)); // 限制流的元素?cái)?shù)量,然后打印 randomIntStream .limit(10) .forEach(System.out::println); } }
在這個(gè)示例中,我們使用Stream.generate
靜態(tài)工廠方法創(chuàng)建了一個(gè)包含隨機(jī)整數(shù)的Stream流。然后,我們使用limit
操作限制了流中元素的數(shù)量,最后打印出了生成的隨機(jī)整數(shù)。
這些靜態(tài)工廠方法為創(chuàng)建不同類型的Stream提供了便捷的途徑,使流的創(chuàng)建更加靈活和便捷。
4.使用 Stream.Builder
Stream.Builder
是Java 8引入的用于構(gòu)建流的一種方式。它允許逐個(gè)添加元素到流中,并最終構(gòu)建一個(gè)Stream對(duì)象。這對(duì)于在迭代或生成元素的過程中構(gòu)建流非常有用。
下面是如何使用Stream.Builder
創(chuàng)建流的詳細(xì)介紹,并提供兩個(gè)代碼示例。
使用Stream.Builder創(chuàng)建流的步驟
- 創(chuàng)建Stream.Builder對(duì)象:首先,需要?jiǎng)?chuàng)建一個(gè)
Stream.Builder
對(duì)象。 - 添加元素:然后,使用
Stream.Builder
的add
方法逐個(gè)添加元素到流中。 - 構(gòu)建流:一旦添加了所有元素,可以調(diào)用
Stream.Builder
的build
方法來構(gòu)建Stream對(duì)象。
示例1:使用Stream.Builder創(chuàng)建流并過濾奇數(shù)
import java.util.stream.Stream; public class StreamBuilderExample { public static void main(String[] args) { Stream.Builder<Integer> builder = Stream.builder(); // 添加元素到Stream for (int i = 1; i <= 10; i++) { builder.accept(i); } // 構(gòu)建Stream Stream<Integer> numberStream = builder.build(); // 使用Stream操作 numberStream .filter(n -> n % 2 == 0) // 過濾偶數(shù) .forEach(System.out::println); } }
在這個(gè)示例中,我們首先創(chuàng)建了一個(gè)Stream.Builder
對(duì)象,然后使用accept
方法逐個(gè)添加1到10的整數(shù)到流中,最后使用filter
中間操作篩選出偶數(shù)并使用forEach
終端操作打印出結(jié)果。
示例2:使用Stream.Builder生成斐波那契數(shù)列
import java.util.stream.Stream; public class FibonacciStreamExample { public static void main(String[] args) { Stream.Builder<Long> builder = Stream.builder(); long a = 0, b = 1; int count = 10; for (int i = 0; i < count; i++) { builder.accept(a); long next = a + b; a = b; b = next; } Stream<Long> fibonacciStream = builder.build(); fibonacciStream.forEach(System.out::println); } }
在這個(gè)示例中,我們使用Stream.Builder
生成斐波那契數(shù)列的前10個(gè)數(shù)字。我們首先創(chuàng)建一個(gè)Stream.Builder
對(duì)象,然后使用循環(huán)逐個(gè)添加斐波那契數(shù)列的元素,最后使用forEach
終端操作打印出結(jié)果。
Stream.Builder
適用于需要逐個(gè)生成元素并構(gòu)建流的情況,使代碼更加清晰和靈活。
5. 從文件創(chuàng)建流
在Java中,可以從文件創(chuàng)建Stream流以便進(jìn)行文件的讀取和處理。通常,可以使用java.nio.file
包中的類來實(shí)現(xiàn)這一目的。以下是如何從文件創(chuàng)建流的方法以及兩個(gè)代碼示例:
方法1:使用Files.lines方法創(chuàng)建文本文件的流
Files.lines
方法允許創(chuàng)建一個(gè)包含文件內(nèi)容的Stream<String>
,適用于文本文件的逐行讀取。該方法接受文件路徑作為參數(shù),并返回一個(gè)Stream
對(duì)象。
下面是一個(gè)示例:
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class FileToStreamExample { public static void main(String[] args) { String filePath = "sample.txt"; // 文件路徑 try (Stream<String> lines = Files.lines(Paths.get(filePath))) { lines.forEach(System.out::println); // 逐行打印文件內(nèi)容 } catch (IOException e) { e.printStackTrace(); } } }
在這個(gè)示例中,我們使用Files.lines
方法打開名為"sample.txt"的文本文件,并將其內(nèi)容逐行打印到控制臺(tái)。
方法2:使用Files.newInputStream方法創(chuàng)建二進(jìn)制文件的流
如果要處理二進(jìn)制文件,例如圖像或音頻文件,可以使用Files.newInputStream
方法創(chuàng)建一個(gè)InputStream
,然后將其轉(zhuǎn)換為Stream
。下面是一個(gè)示例:
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.stream.Stream; public class BinaryFileToStreamExample { public static void main(String[] args) { String filePath = "image.jpg"; // 二進(jìn)制文件路徑 try { Path path = Paths.get(filePath); Stream<Byte> byteStream = Files.newInputStream(path) .map(b -> (byte) b); byteStream.forEach(System.out::println); // 逐字節(jié)打印二進(jìn)制文件內(nèi)容 } catch (IOException e) { e.printStackTrace(); } } }
在這個(gè)示例中,我們使用Files.newInputStream
方法創(chuàng)建一個(gè)輸入流,然后將其映射為Stream<Byte>
,并最終逐字節(jié)打印二進(jìn)制文件的內(nèi)容。
無論是文本文件還是二進(jìn)制文件,從文件創(chuàng)建Stream流都是非常有用的,它使文件的讀取和處理變得更加方便和靈活。在處理文件時(shí),不要忘記適當(dāng)?shù)靥幚砜赡艹霈F(xiàn)的IOException
異常。
以上就是java構(gòu)建Stream流的多種方式總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于java構(gòu)建Stream流的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java讀取配置文件(properties)的時(shí)候,unicode碼轉(zhuǎn)utf-8方式
這篇文章主要介紹了java讀取配置文件(properties)的時(shí)候,unicode碼轉(zhuǎn)utf-8方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02通過Java實(shí)現(xiàn)對(duì)PDF頁面的詳細(xì)設(shè)置
這篇文章主要介紹了通過Java實(shí)現(xiàn)對(duì)PDF頁面的詳細(xì)設(shè)置,下面的示例將介紹通過Java編程來對(duì)PDF頁面進(jìn)行個(gè)性化設(shè)置的方法,包括設(shè)置頁面大小、頁邊距、紙張方向、頁面旋轉(zhuǎn)等,需要的朋友可以參考下2019-07-07restemplate請(qǐng)求亂碼之content-encoding=“gzip“示例詳解
RestTemplate從Spring3.0開始支持的一個(gè)HTTP請(qǐng)求工具,它提供了常見的REST請(qǐng)求方案的模板,及一些通用的請(qǐng)求執(zhí)行方法 exchange 以及 execute,接下來通過本文給大家介紹restemplate請(qǐng)求亂碼之content-encoding=“gzip“,需要的朋友可以參考下2024-03-03MyBatis測(cè)試報(bào)錯(cuò):Cannot?determine?value?type?from?string?&a
這篇文章主要給大家介紹了關(guān)于MyBatis測(cè)試報(bào)錯(cuò):Cannot?determine?value?type?from?string?'xxx'的解決辦法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02一篇文章帶你玩轉(zhuǎn)Spring bean的終極利器
這篇文章主要給大家介紹了關(guān)于玩轉(zhuǎn)Spring bean的終極利器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring bean具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05XML Web 服務(wù) Eclipse實(shí)現(xiàn)sun-jaxws.xml文件的方法
在sun-jaxws.xml文件,可以配置endpoint、handler-chain等內(nèi)容,在這個(gè)文件中配置的內(nèi)容會(huì)覆蓋在Java代碼中使用注解屬性配置的的內(nèi)容,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2023-11-11java8 實(shí)現(xiàn)提取集合對(duì)象的每個(gè)屬性
這篇文章主要介紹了java8 實(shí)現(xiàn)提取集合對(duì)象的每個(gè)屬性方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02