首頁 > Java > java教程 > 主體

Item 優先選擇流中沒有副作用的函數

WBOY
發布: 2024-08-08 16:46:52
原創
662 人瀏覽過

Item  Dê preferência às funções sem efeitos colaterais nas streams

流使用介紹:

  • 新用戶可能會發現很難在流管道中表達計算。
  • 流基於函數式編程,提供表現力、速度和並行化。

計算結構:

  • 使用純函數將結構計算為轉換序列。
  • 純函數只依賴它們的輸入,不會改變狀態。

副作用:

  • 避免傳遞給流操作的函數產生副作用。
  • 不正確使用改變外部狀態的 forEach 是一種「難聞的氣味」。

範例 1:有副作用的程式碼

Map<String, Long> freq = new HashMap<>();
try (Stream<String> words = new Scanner(file).tokens()) {
    words.forEach(word -> {
        freq.merge(word.toLowerCase(), 1L, Long::sum);
    });
}

登入後複製

問題:此程式碼使用 forEach 修改外部狀態(freq)。它是迭代的並且不利用流。

範例 2:無副作用的程式碼

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting()));
}

登入後複製

解決方案: 使用 Collectors.groupingBy 收集器建立頻率表而不更改外部狀態。更短、更清晰、更有效率。

佔用流 API:

  • 模仿迭代循環的程式碼不利用流。
  • 使用收集器進行更有效率和可讀的操作。

收藏家:

  • 簡化將結果收集到列表和集合等集合。
  • Collectors.toList()、Collectors.toSet()、Collectors.toCollection(collectionFactory)。

範例 3:擷取最常見的 10 個單字的清單

List<String> topTen = freq.entrySet().stream()
    .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
    .limit(10)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

登入後複製

說明:

  • 按值的降序排列頻率對映條目。
  • 將流限制為 10 個字。
  • 收集清單中最常見的單字。

收集器 API 的複雜性:

  • API 有 39 種方法,但很多都是進階使用的。
  • 收集器可用於建立映射(toMap、groupingBy)。

地圖與收集策略:

  • toMap(keyMapper, valueMapper) 取得唯一鍵值。
  • 使用合併功能處理鍵衝突的策略。
  • groupingBy 根據分類器函數將元素分組。

範例 4:使用合併功能的 toMap

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(Collectors.toMap(
        String::toLowerCase, 
        word -> 1L, 
        Long::sum
    ));
}

登入後複製

說明:

  • toMap 將單字對應到它們的頻率。
  • 合併函數(Long::sum)透過對頻率求和來處理關鍵衝突。

範例 5:按藝人分組並找出最暢銷的專輯

Map<Artist, Album> topAlbums = albums.stream()
    .collect(Collectors.toMap(
        Album::getArtist,
        Function.identity(),
        BinaryOperator.maxBy(Comparator.comparing(Album::sales))
    ));

登入後複製

說明:

  • toMap 將藝術家映射到他們最暢銷的專輯。
  • BinaryOperator.maxBy 決定每位藝人的最暢銷專輯。

字串集合:
Collectors.joining 將字串與可選分隔符號連接起來。

範例 6:使用分隔符號連接字串

String result = Stream.of("came", "saw", "conquered")
    .collect(Collectors.joining(", ", "[", "]"));

登入後複製

說明:

  • Collectors.joining 使用逗號作為分隔符號、前綴和後綴連接字串。
  • 結果:[來、看見、征服]。

結論:

  • 流的本質在於沒有副作用的函數。
  • forEach 只能用於報告結果。
  • 有關收集器的知識對於有效使用流至關重要。

以上是Item 優先選擇流中沒有副作用的函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!