博客 / 詳情

返回

Java Stream API 操作完全攻略:讓你的代碼更加出色 (三)

前言

  Java Stream 是一種強大的數據處理工具,可以幫助開發人員快速高效地處理和轉換數據流。使用 Stream 操作可以大大簡化代碼,使其更具可讀性和可維護性,從而提高開發效率。本文將為您介紹 Java Stream 操作的所有方面,包括 groupingBy、groupingBy、joining、mapping 等操作,讓你的代碼行雲流水,更加優雅

  1. groupingBy():按照指定條件對 Stream 中的元素進行分組。
  2. partitioningBy():按照指定條件對 Stream 中的元素進行分區。
  3. joining():將 Stream 中的元素連接成一個字符串。
  4. mapping():根據指定的 Function 對 Stream 中的元素進行映射,並返回一個新的 Stream。
  5. flatMapping():將每個元素映射為一個 Stream,然後將這些 Stream 連接成一個 Stream。
  6. iterating():使用指定的種子值創建一個 Stream,並依次對每個元素進行指定的操作。
  7. empty():返回一個空的 Stream。
  8. of():根據指定的元素創建一個 Stream。
  9. concat():將多個 Stream 連接成一個 Stream。
  10. unordered():返回一個無序的 Stream。

示例

1. 使用 groupingBy() 按照字符串長度對字符串列表進行分組

代碼示例:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GroupingByExample {
    public static void main(String[] args) {
        List<String> stringList = Arrays.asList("hello", "world", "java", "stream");

        Map<Integer, List<String>> result = stringList.stream()
                .collect(Collectors.groupingBy(String::length));

        System.out.println(result);
    }
}

輸出結果:

{5=[hello, world], 4=[java], 6=[stream]}

2.使用 partitioningBy() 將數字列表按照是否為偶數進行分區

代碼示例:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PartitioningByExample {
    public static void main(String[] args) {
        List<Integer> numberList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Map<Boolean, List<Integer>> result = numberList.stream()
                .collect(Collectors.partitioningBy(n -> n % 2 == 0));

        System.out.println(result);
    }
}

輸出結果:

{false=[1, 3, 5, 7, 9], true=[2, 4, 6, 8, 10]}

3.使用 joining() 將字符串列表中的元素用逗號連接成一個字符串

代碼示例:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class JoiningByExample {
    public static void main(String[] args) {
        List<String> stringList = Arrays.asList("hello", "world", "java", "stream");

        String result = stringList.stream()
                .collect(Collectors.joining(","));

        System.out.println(result);
    }
}

輸出結果:

hello,world,java,stream

4.使用 mapping() 將字符串列表中的元素轉換為大寫字母

代碼示例:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MappingByExample {
    public static void main(String[] args) {
        List<String> stringList = Arrays.asList("hello", "world", "java", "stream");

        List<String> result = stringList.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());

        System.out.println(result);
    }
}

輸出結果:

[HELLO, WORLD, JAVA, STREAM]

5.使用 flatMapping() 將嵌套的字符串列表展平為一個字符串列表

代碼示例:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FlatMappingByExample {
    public static void main(String[] args) {
        List<List<String>> nestedList = Arrays.asList(
                Arrays.asList("hello", "world"),
                Arrays.asList("hello","java", "stream"));

        List<String> result = nestedList.stream()
                .flatMap(List::stream)
                .distinct()
                .collect(Collectors.toList());

        System.out.println(result);
    }
}

輸出結果:

[hello, world, java, stream]

6.使用 iterating() 生成斐波那契數列前 10 項

代碼示例:

import java.util.stream.Stream;

public class IteratingByExample {
    public static void main(String[] args) {
        Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]})
                .limit(10)
                .map(t -> t[0])
                .forEach(System.out::println);
    }
}

輸出結果:

0
1
1
2
3
5
8
13
21
34

7.使用 empty() 使用空的 Stream

代碼示例:

import java.util.stream.Stream;

public class EmptyStreamExample {
    public static void main(String[] args) {
        Stream<String> emptyStream = Stream.empty();

        System.out.println(emptyStream.count());
    }
}

輸出結果:

0

8.使用 of() 創建包含一些字符串的 Stream

代碼示例:

import java.util.stream.Stream;

public class OfStreamExample {
    public static void main(String[] args) {
        Stream<String> stringStream = Stream.of("hello", "world", "java", "stream");

        stringStream.forEach(System.out::println);
    }
}

輸出結果:

hello
world
java
stream

9.使用 concat() 將兩個字符串列表合併為一個列表

代碼示例:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class ConcatStreamExample {
    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("hello", "world");
        List<String> list2 = Arrays.asList("java", "stream");

        Stream<String> stream1 = list1.stream();
        Stream<String> stream2 = list2.stream();

        List<String> result = Stream.concat(stream1, stream2)
                .collect(Collectors.toList());

        System.out.println(result);
    }
}

輸出結果:

[hello, world, java, stream]

10.使用 unordered() 對數字列表進行排序後,使用 unordered()返回一個無序的 Stream

代碼示例:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class UnorderedStreamExample {
    public static void main(String[] args) {
        List<Integer> numberList = Arrays.asList(1, 3, 2, 4, 10, 6, 8, 7, 9, 6);

        List<Integer> result = numberList.stream()
                .sorted()
                .unordered()
                .collect(Collectors.toList());

        System.out.println(result);
    }
}

輸出結果:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

來個小坑

  感謝大佬看到這裏,如果你看完覺得沒問題,那麼你需要反思一下了哦。好了我們可以在仔細地看看,示例10.unordered()的代碼。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class UnorderedStreamExample {
    public static void main(String[] args) {
        List<Integer> numberList = Arrays.asList(1, 3, 2, 4, 10, 6, 8, 7, 9, 6);

        List<Integer> result = numberList.stream()
                .sorted()
                .unordered()
                .collect(Collectors.toList());

        System.out.println(result);
    }
}

輸出結果:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

  執行過程分析,首先輸入了一個無序的流,然後使用sorted()對流進行排序,然後在使用unordered(),去除流的有序約束。然後輸出為List,在進行打印出來。按理來説,輸出的順序應該是一個無需的,而不是有序的。

解答

  unordered()操作不會執行任何操作來顯式地對流進行排序。它的作用是消除了流必須保持有序的約束,從而允許後續操作使用不必考慮排序的優化。

  對於順序流,順序的存在與否不會影響性能,隻影響確定性。如果流是順序的,則在相同的源上重複執行相同的流管道將產生相同的結果;如果是非順序流,重複執行可能會產生不同的結果。

  unordered()操作,是消除了流必須保持有序的約束。並不會改變,流原有的順序。對於並行流,放寬排序約束有時可以實現更高效的執行。在流有序時, 但用户不特別關心該順序的情況下,使用 unordered() 明確地對流進行去除有序約束可以改善某些有狀態或終端操作的並行性能。

參考

https://segmentfault.com/q/1010000017969473

結尾

  如果覺得對你有幫助,可以多多評論,多多點贊哦,也可以到我的主頁看看,説不定有你喜歡的文章,也可以隨手點個關注哦,謝謝。

  我是不一樣的科技宅,每天進步一點點,體驗不一樣的生活。我們下期見!

user avatar shenbl 頭像 madrid 頭像 shiwangdeshuanggang_ejn3li 頭像 u_17353299 頭像 xindoo 頭像
5 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.