最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?Stream流常用方法實戰(zhàn)指南

 更新時間:2026年01月20日 10:21:34   作者:madao哦  
Stream流是Java 8中的一個新特性,它提供了一種處理集合和數(shù)組的方式,Stream流可以讓我們以一種更加簡潔、高效、可讀性更強的方式來處理數(shù)據(jù),這篇文章主要介紹了Java?Stream流常用方法的相關(guān)資料,需要的朋友可以參考下

前言

在 Java 8 引入的眾多特性中,Stream API 無疑是最能提升代碼優(yōu)雅度和開發(fā)效率的工具之一。它讓我們能以聲明式的方式處理數(shù)據(jù)集合(類似于 SQL 語句),告別了繁瑣的 for 循環(huán)和復雜的邏輯判斷。

本文將基于實戰(zhàn)角度,帶你全面掌握 Stream 流的創(chuàng)建中間操作、終結(jié)操作以及方法引用的高級用法。

一、 不可變集合

在開始學習 Stream 之前,了解 JDK 9+ 引入的不可變集合工廠方法非常有用,它們常被用來快速創(chuàng)建測試數(shù)據(jù)。

  • List 和 SetList.of() 和 Set.of(),形參依次傳入 value。

  • MapMap.of(),形參依次傳入 key 和 value。

// 示例
List<String> list = List.of("張三", "李四", "王五");
Set<String> set = Set.of("A", "B", "C");
Map<String, Integer> map = Map.of("張三", 18, "李四", 20);

二、 第一步:獲取 Stream 流

Stream 流的生命周期始于“數(shù)據(jù)源”。不同的數(shù)據(jù)結(jié)構(gòu)獲取流的方式略有不同。

1. 單列集合 (List, Set)

直接調(diào)用集合的 .stream() 方法。

ArrayList<String> list = new ArrayList<>();
Stream<String> stream = list.stream();

2. 雙列集合 (Map)

Map 本身不能直接獲取流,需要先將其轉(zhuǎn)換為單列集合(KeySet 或 EntrySet)后再獲取。

HashMap<String, Integer> map = new HashMap<>();

// 1. 對鍵獲取流
Stream<String> keyStream = map.keySet().stream();

// 2. 對鍵值對獲取流 (常用)
Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();

3. 數(shù)組

使用 Arrays 工具類的靜態(tài)方法。

int[] arr = {1, 2, 3};
IntStream stream = Arrays.stream(arr); 

4. 零散數(shù)據(jù)

使用 Stream.of() 靜態(tài)方法。

注意:如果傳入的是基本數(shù)據(jù)類型的數(shù)組(如 int[]),Stream.of 會把整個數(shù)組當成一個元素(即傳遞的是地址);引用類型數(shù)組則會正常展開。

Stream<Integer> stream = Stream.of(1, 2, 3, 4);

三、 第二步:Stream 中間方法 (Intermediate Operations)

中間方法具有惰性求值的特點:它們不會立即執(zhí)行,只有當遇到“終結(jié)方法”時,整個流水線才會啟動。

核心規(guī)則

Stream 流只能使用一次,復用會報錯,建議使用鏈式編程

中間操作不會修改原集合的數(shù)據(jù)。

1. 篩選與切片

  • filter(Predicate):過濾。返回 false 代表當前數(shù)據(jù)舍棄,返回 true 代表保留。

    // 留下 list 中以“張”開頭的數(shù)據(jù)
    list.stream().filter(ele -> ele.startsWith("張"));
    
  • limit(n):截斷流,只取前 n 個數(shù)據(jù)。

  • skip(n):跳過流,扔掉前 n 個數(shù)據(jù)。

  • distinct():元素去重。

    注意:該方法依賴元素的 hashCode() 和 equals() 方法。如果是自定義對象,請務必重寫這兩個方法。

2. 組合 (Concat)

  • Stream.concat(a, b):將兩個流合并為一個流。

3. 映射 (Map & FlatMap)

  • map(Function):轉(zhuǎn)換流中的數(shù)據(jù)類型。

    // 示例:將 "張三-20" 這種字符串轉(zhuǎn)為 int 類型的年齡
    List<String> list = Arrays.asList("張三-20", "李四-18");
    
    list.stream()
        .map(s -> Integer.parseInt(s.split("-")[1])) // 字符串轉(zhuǎn)數(shù)字
        .forEach(System.out::println);
    
  • flatMap(Function):扁平化映射。主要作用是將一個流中的每個元素映射成一個新的流,然后將這些新的流合并成一個單一的流。

    // 示例:將嵌套列表 [[1,2], [3,4], [5,6]] 展平為 [1,2,3,4,5,6]
    List<List<Integer>> listOfLists = Arrays.asList(
        Arrays.asList(1, 2),
        Arrays.asList(3, 4),
        Arrays.asList(5, 6)
    );
    
    List<Integer> flattenedList = listOfLists.stream()
        .flatMap(List::stream) // 將每個小 List 變成 Stream
        .collect(Collectors.toList());
    

4. 排序 (Sorted)

  • sorted():根據(jù)自然順序排序(要求元素實現(xiàn) Comparable 接口)。

  • sorted(Comparator):通過自定義比較器排序。

    升序示例

    // 先按年齡排序,年齡相同則按名字排序
    List<Person> sortedList = people.stream()
        .sorted(Comparator.comparing(Person::getAge)
                          .thenComparing(Person::getName))
        .collect(Collectors.toList());
    

    降序示例: 可以在 comparing 后面鏈式調(diào)用 .reversed(),或者直接使用 Comparator.reverseOrder()。

    // 按年齡降序
    people.stream().sorted(Comparator.comparing(Person::getAge).reversed());
    

5. 調(diào)試 (Peek)

  • peek(Consumer):類似于 forEach,但它是一個中間操作。通常用于在流的各個階段打印日志,觀察數(shù)據(jù)流向,而不打斷流的處理。

四、 第三步:Stream 終結(jié)方法 (Terminal Operations)

終結(jié)方法是流操作的最后一步,調(diào)用后流即關(guān)閉,無法再次使用。

1. 遍歷與統(tǒng)計

  • forEach(Consumer):遍歷操作,返回值為 void。

    stream.forEach(ele -> System.out.println(ele));
    
  • count():返回流中數(shù)據(jù)的個數(shù)(long 類型)。

2. 查找與匹配

  • anyMatch(Predicate):判斷流中是否包含任意一個滿足條件的元素。

  • allMatch(Predicate):判斷流中是否所有元素都滿足條件。

  • findFirst():返回流中的第一個元素(返回類型為 Optional)。

3. 數(shù)組轉(zhuǎn)換

  • toArray()

    • 不傳參:返回 Object[]。

    • 傳參:返回指定類型的數(shù)組。

    // lambda 表達式中的 value 代表數(shù)組的長度
    String[] arr = stream.toArray(value -> new String[value]);
    // 或者使用方法引用
    String[] arr2 = stream.toArray(String[]::new);
    

4. 歸約 (Reduce)

  • reduce():用于將流中的所有元素結(jié)合起來,得到一個值。例如求和、求最大值等。

    // 計算 1-10 的和
    Integer sum = Stream.iterate(1, x -> x + 1).limit(10)
                        .reduce(0, (a, b) -> a + b);
    

5. 收集 (Collect)

這是最常用的終結(jié)方法,將流轉(zhuǎn)變?yōu)榧匣蚱渌麛?shù)據(jù)結(jié)構(gòu)。

  • Collectors.toList() / toSet():收集到 List 或 Set 中。

  • Collectors.toMap():收集到 Map 中。

    注意:toMap 如果遇到重復的 Key 會報錯,建議處理 Key 沖突。

    示例:將 "名字-性別-年齡" 格式的數(shù)據(jù)轉(zhuǎn)為 Map,以名字為 Key,年齡為 Value。

    List<String> list = Arrays.asList("張三-男-20", "李四-女-18");
    
    Map<String, Integer> map = list.stream()
        .collect(Collectors.toMap(
            s -> s.split("-")[0],                // Key: 名字
            s -> Integer.parseInt(s.split("-")[2]) // Value: 年齡
        ));
    
  • Collectors.groupingBy()分組(高頻用法)。 根據(jù)某個分類函數(shù)對流中的元素進行分組,返回一個 Map。

    場景 1:基礎(chǔ)分組

    // 按照年齡分組,返回 Map<Integer, List<Person>>
    Map<Integer, List<Person>> peopleByAge = people.stream()
        .collect(Collectors.groupingBy(Person::getAge));
    

    場景 2:分組并統(tǒng)計

    // 按照年齡分組,并計算每個年齡段的人數(shù),返回 Map<Integer, Long>
    Map<Integer, Long> peopleCountByAge = people.stream()
        .collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));
    

五、 進階:方法引用 (Method References)

當 Lambda 表達式體中僅僅是調(diào)用一個已存在的方法時,可以使用方法引用 :: 來簡化代碼,使代碼更具可讀性。

1. 靜態(tài)方法引用

格式:ClassName::staticMethod

// Lambda: s -> Integer.parseInt(s)
// 引用:   Integer::parseInt
list.stream().map(Integer::parseInt).collect(Collectors.toList());

2. 實例方法引用

格式:object::instanceMethod (對象名::成員方法)

StringBuilder sb = new StringBuilder();
// Lambda: s -> sb.append(s)
// 引用:   sb::append
list.stream().forEach(sb::append);

3. 特定類型的任意對象的實例方法引用

格式:ClassName::method 適用場景:Lambda 的第一個參數(shù)是方法的調(diào)用者,后面的參數(shù)是方法的形參。

List<String> words = Arrays.asList("apple", "banana");

// Lambda: (s) -> s.length()  --> 相當于調(diào)用 "apple".length()
// 引用:   String::length
List<Integer> lengths = words.stream()
    .map(String::length)
    .collect(Collectors.toList());

4. 構(gòu)造方法引用

格式:ClassName::new

List<String> names = Arrays.asList("Alice", "Bob");

// Lambda: name -> new Person(name)
// 引用:   Person::new
List<Person> people = names.stream()
    .map(Person::new)
    .collect(Collectors.toList());

六、 總結(jié)

Java Stream API 的核心流程可以概括為: 數(shù)據(jù)源 (Source) -> 中間操作 (Intermediate) -> 終結(jié)操作 (Terminal)

到此這篇關(guān)于Java Stream流常用方法實戰(zhàn)指南的文章就介紹到這了,更多相關(guān)Java Stream流常用方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

湛江市| 皮山县| 二连浩特市| 东安县| 志丹县| 晋中市| 梅州市| 建水县| 观塘区| 长乐市| 广河县| 临西县| 锡林浩特市| 岑巩县| 普兰县| 宁强县| 石渠县| 洛隆县| 沙田区| 西乡县| 台北县| 子长县| 贵南县| 石泉县| 玛沁县| 华宁县| 腾冲县| 蕉岭县| 普兰店市| 河东区| 宁陕县| 广州市| 陵川县| 韶关市| 阿克陶县| 曲松县| 郎溪县| 湟中县| 孝义市| 桐城市| 大冶市|