Java Stream常見用法彙總,開發效率大幅提升

来源:https://www.cnblogs.com/tyson03/archive/2023/04/14/17320021.html
-Advertisement-
Play Games

本文已經收錄到Github倉庫,該倉庫包含電腦基礎、Java基礎、多線程、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分散式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~ Github地址 如果訪問不了Github,可以訪 ...


本文已經收錄到Github倉庫,該倉庫包含電腦基礎、Java基礎、多線程、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分散式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~

Github地址

如果訪問不了Github,可以訪問gitee地址。

gitee地址


Java8 新增的 Stream 流大大減輕了我們代碼的工作量,但是 Stream 流的用法較多,實際使用的時候容易遺忘,整理一下供大家參考。

1. 概述

Stream 使用一種類似用 SQL 語句從資料庫查詢數據的直觀方式來對 Java 集合運算和表達的高階抽象。

Stream API 可以極大提高 Java 程式員的生產力,讓程式員寫出高效率、乾凈、簡潔的代碼。

這種風格將要處理的元素集合看作一種流, 流在管道中傳輸, 並且可以在管道的節點上進行處理, 比如篩選, 排序,聚合等。

2. 創建

2.1 集合自帶 Stream 流方法

List<String> list = new ArrayList<>();
// 創建一個順序流
Stream<String> stream = list.stream();
// 創建一個並行流
Stream<String> parallelStream = list.parallelStream();

2.1 通過 Array 數組創建

最全面的Java面試網站

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

2.3 使用 Stream 的靜態方法創建

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream = Stream.iterate(0, (x) -> x + 3).limit(3); // 輸出 0,3,6

Stream<String> stream = Stream.generate(() -> "Hello").limit(3); // 輸出 Hello,Hello,Hello
Stream<Double> stream = Stream.generate(Math::random).limit(3); // 輸出3個隨機數

2.3 數值流

// 生成有限的常量流
IntStream intStream = IntStream.range(1, 3); // 輸出 1,2
IntStream intStream = IntStream.rangeClosed(1, 3); // 輸出 1,2,3
// 生成一個等差數列
IntStream.iterate(1, i -> i + 3).limit(5).forEach(System.out::println); // 輸出 1,4,7,10,13
// 生成無限常量數據流
IntStream generate = IntStream.generate(() -> 10).limit(3); // 輸出 10,10,10

另外還有 LongStream、DoubleStream 都有這幾個方法。

3. 使用

初始化一些數據,示例中使用。

public class Demo {
    class User{
        // 姓名
        private String name;

        // 年齡
        private Integer age;
    }

    public static void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User("Tom", 1));
        users.add(new User("Jerry", 2));
    }
}

3.1 遍歷 forEach

// 迴圈輸出user對象
users.stream().forEach(user -> System.out.println(user));

3.2 查找 find

// 取出第一個對象
User user = users.stream().findFirst().orElse(null); // 輸出 {"age":1,"name":"Tom"}
// 隨機取出任意一個對象
User user = users.stream().findAny().orElse(null);

3.3 匹配 match

// 判斷是否存在name是Tom的用戶
boolean existTom = users.stream().anyMatch(user -> "Tom".equals(user.getName()));
// 判斷所有用戶的年齡是否都小於5
boolean checkAge = users.stream().allMatch(user -> user.getAge() < 5);

3.4 篩選 filter

// 篩選name是Tom的用戶
users.stream()
        .filter(user -> "Tom".equals(user.name))
        .forEach(System.out::println); // 輸出 {"age":1,"name":"Tom"}

3.5 映射 map/flatMap

// 列印users里的name
users.stream().map(User::getName).forEach(System.out::println); // 輸出 Tom Jerry
// List<List<User>> 轉 List<User>
List<List<User>> userList = new ArrayList<>();
List<User> users = userList.stream().flatMap(Collection::stream).collect(Collectors.toList());

3.6 歸約 reduce

// 求用戶年齡之和
Integer sum = users.stream().map(User::getAge).reduce(Integer::sum).orElse(0);
// 求用戶年齡的乘積
Integer product = users.stream().map(User::getAge).reduce((x, y) -> x * y).orElse(0);

3.7 排序 sorted

// 按年齡倒序排
List<User> collect = users.stream()
        .sorted(Comparator.comparing(User::getAge).reversed())
        .collect(Collectors.toList());

//多屬性排序
List<Person> result = persons.stream()
                .sorted(Comparator.comparing((Person p) -> p.getNamePinyin())
                        .thenComparing(Person::getAge)).collect(Collectors.toList());

3.8 收集 collect

// list轉換成map
Map<Integer, User> map = users.stream()
        .collect(Collectors.toMap(User::getAge, Function.identity()));

// 按年齡分組
Map<Integer, List<User>> userMap = users.stream().collect(Collectors.groupingBy(User::getAge));

// 求平均年齡
Double ageAvg = users.stream().collect(Collectors.averagingInt(User::getAge)); // 輸出 1.5

// 求年齡之和
Integer ageSum = users.stream().collect(Collectors.summingInt(User::getAge));

// 求年齡最大的用戶
User user = users.stream().collect(Collectors.maxBy(Comparator.comparing(User::getAge))).orElse(null);

// 把用戶姓名拼接成逗號分隔的字元串輸出
String names = users.stream().map(User::getName).collect(Collectors.joining(",")); // 輸出 Tom,Jerry

3.9 List 轉換成 Map 時遇到重覆主鍵

這樣轉換會報錯,因為 ID 重覆。

可以這樣做

好東西應該要分享出來!我把自己學習電腦多年以來的書籍分享出來了,彙總到一個電腦經典編程書籍倉庫了,一共300多本,包括C語言、C++、Java、Python、前端、資料庫、操作系統、電腦網路、數據結構和演算法、機器學習、編程人生等,可以star一下,下次找書直接在上面搜索,倉庫持續更新中~

Github地址


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作者羅錦華,API7.ai 技術專家/技術工程師,開源項目 pgcat,lua-resty-ffi,lua-resty-inspect 的作者。 原文鏈接 為什麼需要 Lua 動態調試插件? Apache APISIX 有很多 Lua 代碼,如何在運行時不觸碰源代碼的情況下,檢查代碼裡面的變數值? ...
  • 和女朋友坐一塊的時候,突然想到了,哈哈哈哈哈 不會很難!!! import java.util.*; import java.lang.Math; // 註意類名必須為 Main, 不要有任何 package xxx 信息 public class Main { public static void ...
  • Flask-SQLAlchemy MySQL是免費開源軟體,大家可以自行搜索其官網(https://www.MySQL.com/downloads/) 測試MySQL是否安裝成功 在所有程式中,找到MySQL→MySQL Server 5.6下麵的命令行工具,然後單擊輸入密碼後回車,就可以知道MyS ...
  • 前言 在上一篇文章中,我們介紹了~運算符的高級用法,本篇文章,我們將介紹<< 運算符的一些高級用法。 一、人物簡介 第一位閃亮登場,有請今後會一直教我們C語言的老師 —— 自在。 第二位上場的是和我們一起學習的小白程式猿 —— 逍遙。 二、計算2的整數次冪 代碼示例 #include <stdio. ...
  • 布隆過濾器是一個精巧而且經典的數據結構。 你可能沒想到: RocketMQ、 Hbase 、Cassandra 、LevelDB 、RocksDB 這些知名項目中都有布隆過濾器的身影。 對於後端程式員來講,學習和理解布隆過濾器有很大的必要性。來吧,我們一起品味布隆過濾器的設計之美。 1 緩存穿透 我 ...
  • Java + Jpcap實現監控 IP包流量 說明:本設計是電腦網路課程的課設,因為代碼是提前實現的,本博客於後期補上,又因為代碼沒寫註釋自己也看不懂了,所以,僅供參考,就當提供一種實現方式。 文中提供的《Jpcap中文API文檔》來源於網路,本文僅用於學習交流,如有侵權,可聯繫我進行刪除。 效果 ...
  • 是什麼 迴圈隊列, FIFO先進先出 怎麼用 初始化 //C11 deque<int> deq{1,2,3,4,5}; //拷貝構造,可以拷貝deque queue<int> que(deq); //100個5 queue<int> que2(100,5); //運算符重載 que2 = que; ...
  • 集合的理解和好處 數組一旦定義,長度即固定,不能修改。要添加新元素需要新建數組,然後迴圈拷貝,非常麻煩 集合可以動態保存任意多個對象,使用比較方便 提供餓了一系列方便的操作對象的方法:add、remove、set、get等 使用集合添加、刪除新元素的示意代碼,簡潔明瞭 集合主要是兩組(單列集合,雙列 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...