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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...