介紹
Java Stream API 是 Java 8 中新引入的一種數據處理方式。它的目標是提供一種簡單、高效、並行的處理集合、數組等數據源的方式,以取代原有的 for 循環和迭代器。Java Stream API 通過使用聚合操作(aggregation operation)操縱數據流,獲取或轉換數據。
前置知識
在深入學習 Java Stream API 之前,我們需要先掌握以下概念:
- 函數式接口(Functional Interface):函數式接口是只有一個抽象方法的接口。
- Lambda 表達式:Lambda 表達式 是一種簡潔的,代碼行數少的而且可傳遞的對象,可以將 Lambda 表達式看作一段可以傳遞的代碼。它無需命名,旨在簡化 Java 程序中單一方法的某些語法的編寫。Lambda 方式可以使用 Functional Interface 來實現。
Stream API 的主要特點
Java Stream API 的主要特點可歸結為以下幾點:
- 內部迭代:Java Stream API 在迭代時會自動選擇並行或順序執行,無需手動進行線程管理。
- 一次執行:可以對源數據執行各種中間過程和操作,最終只進行一次完成操作。
- 不可變:Java Stream API 操作的結果是新流,源數據不變。
- 延遲執行:Java Stream API 的操作是惰性的,只有在最終執行中間過程的操作時才會被執行。
常用操作
篩選操作
篩選操作指的是通過保留或去除元素來篩選出需要的結果。以下是常用的篩選操作。
filter(Predicate)
filter
方法接收一個 Predicate 函數式接口作為參數,返回一個只包含符合條件的元素的 Stream。
Stream<T> filter(Predicate<? super T> predicate)
示例:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
Stream<String> filtered = strings.stream().filter(string -> !string.isEmpty());
filtered.forEach(System.out::println); //輸出不為空的字符串,即除了“”之外的字符串
distinct()
distinct
方法返回由不同的元素組成的 Stream。
Stream<T> distinct()
示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 1, 3, 2, 4);
Stream<Integer> distinctNumbers = numbers.stream().distinct();
distinctNumbers.forEach(System.out::println); //輸出不重複的整數
映射操作
映射操作指的是將一個流中的元素映射到另一個流中。以下是常用的映射操作。
map(Function)
map
方法用於將元素按照指定的 Function 轉換成另外的元素。Function 函數式接口接收一個參數並返回一個值。
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
示例:
List<String> strings = Arrays.asList("abc", "efg", "qwerty");
Stream<Integer> mapped = strings.stream().map(String::length); //映射字符串的長度
mapped.forEach(System.out::println); //輸出各個字符串的長度
flatMap(Function)
flatMap
方法接收一個 Function 函數式接口作為參數,可以將嵌套的 Stream 展平成一個 Stream。
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
示例:
List<List<String>> list = new ArrayList<>();
list.add(Arrays.asList("apple", "banana"));
list.add(Arrays.asList("orange", "lemon", "grape"));
Stream<String> flatMapped = list.stream().flatMap(Collection::stream);
flatMapped.forEach(System.out::println); //輸出展平後的字符串
排序操作
排序操作指對數據集合進行排序。Java Stream API 提供了兩種方式進行排序:自然排序和定製排序。
sorted()
sorted
方法根據自然排序對源集合進行排序。
Stream<T> sorted()
示例:
List<String> strings = Arrays.asList("ccc", "aaa", "bbb", "ddd");
Stream<String> sorted = strings.stream().sorted();
sorted.forEach(System.out::println); //自然排序
sorted(Comparator)
sorted
方法根據指定的 Comparator 接口對源集合進行排序。
Stream<T> sorted(Comparator<? super T> comparator)
示例:
List<String> strings = Arrays.asList("ccc", "aaa", "bbb", "ddd");
Stream<String> sorted = strings.stream().sorted((s1,s2)->s1.length()-s2.length());
sorted.forEach(System.out::println); //按字符串長度排序
聚合操作
聚合操作指獲取操作結果的操作,包括歸約、收集等操作。
reduce(T identity, BinaryOperator)
reduce
方法接收一個初始值和一個 BinaryOperator(t,t)->t 函數,將集合中的元素逐一與上一個結果進行操作,返回一個包含操作結果的 Optional 對象。
T reduce(T identity, BinaryOperator<T> accumulator)
示例:
List<Integer> numbers = Arrays.asList(1,2,3,4);
Optional<Integer> sum = numbers.stream().reduce(0, (x,y)->x+y); //計算整數的和
sum.ifPresent(System.out::println); //輸出求和的結果
collect(Collector)
collect
方法使用 Collectors 工廠類提供的方法將流轉換成集合、映射、字符串等,以操作結果的形式返回。
R collect(Collector<? super T, A, R> collector)
示例:
List<String> strings = Arrays.asList("abc", "def", "ghi");
List<String> collected = strings.stream().filter(s->s.startsWith("a")).collect(Collectors.toList());
collected.forEach(System.out::println); //輸出以“a”開頭的字符串
小結
Java Stream API 通過內部迭代的方式提供了一種高效、並行的數據處理方式,避免了原有的 for 循環和迭代器的繁瑣操作。通過上述常用操作,我們可以方便地對集合、數據進行篩選、映射、排序、聚合等操作,以得到我們預期的結果。通過學習 Java Stream API,我們可以更加輕鬆地對數據進行操作,提高開發效率。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/248960.html