首頁 >Java >java教程 >掌握 Java Streams:開發人員完整指南

掌握 Java Streams:開發人員完整指南

Linda Hamilton
Linda Hamilton原創
2024-11-27 19:53:10872瀏覽

Mastering Java Streams: A Complete Guide for Developers

Java 8 中引入的 Java Streams 是該語言最強大的補充之一。它們支援對集合和序列進行函數式操作,改變了我們在 Java 中處理資料的方式。流簡化了過濾、映射和收集資料等任務,同時也支援並行操作以提高效能。在這篇文章中,我們將探討 Streams 的基礎知識,討論它們支援的操作類型,並提供範例來幫助您充分利用這項基本功能。

目錄

1.  What is Streams and why we need it?
2.  Types of Streams: Intermediate vs. Terminal
3.  Creating Streams in Java
4.  Intermediate Stream Operations
5.  Terminal Stream Operations
6.  Using Streams with Lambdas
7.  Conclusion

什麼是 Streams 以及為什麼我們需要它?

Java 中的流提供了一種處理資料集合的強大方法。它們允許我們對集合的元素執行功能操作,例如過濾和轉換,而無需改變底層資料。串流幫助開發人員專注於他們想要實現的目標,而不是如何實現它,為資料處理提供了更高層次的抽象。

Java 8 中引入了流以及 lambda 表達式和函數式接口,旨在使 Java 更具表現力並減少樣板程式碼。透過合併流,Java 開始擁抱函數式程式設計範式,允許更乾淨、更簡潔的程式碼。

流的主要優點

  • 聲明式資料處理:描述您想要執行的操作,而不是手動管理循環和條件。
  • 不變性和無狀態性:流操作不會修改來源資料結構。
  • 並行處理:支援並行流,允許輕鬆地將操作分佈在多個執行緒上。

流類型:中間流與終端流

流分為兩種主要類型:

  • 中間操作:這些操作轉換流,並傳回另一個流作為結果。它們是惰性的——這意味著它們在調用終端操作之前不會執行。
  • 終端操作:這些操作觸發流的資料處理並傳回非流結果(例如,集合、單一值或布林值)。一旦執行了終端操作,流就被視為已消耗並且不能被重複使用。

範例:

List<String> names = List.of("Alice", "Bob", "Charlie", "David");

// Intermediate (lazy) operations: filter and map
Stream<String> stream = names.stream()
                             .filter(name -> name.startsWith("A"))
                             .map(String::toUpperCase);

// Terminal operation: collect
List<String> filteredNames = stream.collect(Collectors.toList());
System.out.println(filteredNames); // Output: [ALICE]

在這個範例中,filter和map是中間操作,直到呼叫終端操作collect後才會執行。

在 Java 中建立流

Java 提供了多種建立流的方法,可以輕鬆開始處理資料。

  • 來自收藏

建立流最常見的方法是使用 List、Set 和 Map 等集合。

1.  What is Streams and why we need it?
2.  Types of Streams: Intermediate vs. Terminal
3.  Creating Streams in Java
4.  Intermediate Stream Operations
5.  Terminal Stream Operations
6.  Using Streams with Lambdas
7.  Conclusion
  • 來自數組
List<String> names = List.of("Alice", "Bob", "Charlie", "David");

// Intermediate (lazy) operations: filter and map
Stream<String> stream = names.stream()
                             .filter(name -> name.startsWith("A"))
                             .map(String::toUpperCase);

// Terminal operation: collect
List<String> filteredNames = stream.collect(Collectors.toList());
System.out.println(filteredNames); // Output: [ALICE]
  • 使用 Stream.of
List<String> names = List.of("Alice", "Bob", "Charlie");
Stream<String> nameStream = names.stream();
  • 無限流(生成流)

Java 允許使用 Stream.generate 和 Stream.iterate 建立無限流。

String[] namesArray = {"Alice", "Bob", "Charlie"};
Stream<String> nameStream = Arrays.stream(namesArray);

中間流操作

中間操作傳回一個新流且是惰性的。這意味著它們僅在調用終端操作時執行。

  • 過濾器(謂詞

依條件過濾元素。

Stream<String> stream = Stream.of("Alice", "Bob", "Charlie");
  • map(函數)

將元素從一種類型轉換為另一種類型。

Stream<Double> randomNumbers = Stream.generate(Math::random).limit(5);
Stream<Integer> counting = Stream.iterate(0, n -> n + 1).limit(5);
  • 已排序(比較器

依自然順序或基於比較器對元素進行排序。

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
                                   .filter(n -> n % 2 == 0)
                                   .collect(Collectors.toList());
  • 查看(消費者

對每個元素執行操作,通常對於偵錯很有用。

List<String> names = List.of("Alice", "Bob");
List<Integer> nameLengths = names.stream()
                                 .map(String::length)
                                 .collect(Collectors.toList());

終端流操作

最後執行終端操作,觸發實際的資料處理並傳回最終結果。

  • forEach(消費者

對流中的每個元素執行一個操作。

List<String> names = List.of("Bob", "Alice", "Charlie");
List<String> sortedNames = names.stream()
                                .sorted()
                                .collect(Collectors.toList());
  • 收集(收藏家)

將流的元素收集到集合、列表、集合或其他資料結構中。

List<String> names = List.of("Alice", "Bob");
names.stream()
     .peek(name -> System.out.println("Processing " + name))
     .collect(Collectors.toList());
  • 計數()

計算流中元素的數量。

List<String> names = List.of("Alice", "Bob");
names.stream().forEach(System.out::println);
  • anyMatch(謂詞)、allMatch(謂詞)、noneMatch(謂詞)

檢查是否有任何、全部或沒有元素符合給定條件。

List<String> names = List.of("Alice", "Bob");
Set<String> nameSet = names.stream().collect(Collectors.toSet());
  • findFirst() 和 findAny()

傳回一個可選描述流的第一個或任何元素。

List<String> names = List.of("Alice", "Bob");
long count = names.stream().count();

將流與 Lambda 結合使用

流和 lambda 表達式齊頭並進。由於串流基於函數式接口,因此它們可以與 lambda 無縫協作,從而實現富有表現力且簡潔的資料處理。

例如,過濾名稱列表以查找以“A”開頭的名稱,然後將其轉換為大寫:

List<String> names = List.of("Alice", "Bob", "Charlie");
boolean hasAlice = names.stream().anyMatch(name -> name.equals("Alice"));

在此範例中:

  • 過濾器採用 lambda 名稱 -> name.startsWith("A") 過濾名稱。
  • map 採用方法引用 String::toUpperCase 將名稱轉換為大寫。

結論

Java Streams 為 Java 帶來了函數式程式設計功能,允許進行富有表現力和簡潔的資料操作。透過了解中間操作和終端操作之間的差異以及如何有效地建立和使用流,您可以顯著增強程式碼的可讀性和可維護性。將串流和 lambda 整合到您的工作流程中,以編寫更乾淨、更有效率的 Java 應用程式。

祝直播愉快!

以上是掌握 Java Streams:開發人員完整指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn