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

程式設計師大彬發表於2023-04-21

本文已經收錄到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地址

相關文章