Java 8 中Stream用法

万笑佛發表於2024-05-27

StreamJava 8新增的介面,Stream可以認為是一個高階版本的 Iterator。 廢話不多說直接上程式碼

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@SpringBootTest
class DemoApplicationTests {

    /*
      1.filter:用於根據指定條件過濾元素.它接收一個條件作為引數, 只保留滿足條件的元素, 並生成一個新的Stream
     */
    @Test
    void filterTest() {
        List<String> tempList = Arrays.asList("初一", "初二", "初三", "初四");
        List<String> resList = tempList.stream()
                .filter(s -> s.contains("二"))
                .collect(Collectors.toList());
        System.out.println(resList.toString());
    }

    /*
    2.map:用於對每個元素執行對映操作, 將元素轉換成另一種型別.它接收一個Function(對映函式)作為引數,
          對每個元素應用該對映函式, 並生成一個新的Stream.
    */
    @Test
    void mapTest() {
        List<String> tempList = Arrays.asList("初一", "初二", "初三", "初四");
        List<String> resList = tempList.stream()
                .map(s -> "今天: " + s)
                .collect(Collectors.toList());
        System.out.println(resList.toString());
    }

    /*
    3.sorted():用於對Stream中的元素進行排序,預設按照自然順序進行排序。也可以傳入自定義的Comparator來指定排序規則。
    */
    @Test
    void sortedTest() {
        List<Integer> numList = Arrays.asList(10, 20, 18, 300, 30, 2);
        // ① 預設排序
        List<Integer> orderList = numList.stream()
                .sorted()
                .collect(Collectors.toList());
        System.out.printf("① 預設排序: %s%n", orderList);
        // ② 自定義排序
        List<Integer> orderDescList = numList.stream()
                .sorted((x, y) -> {
                    return y.compareTo(x);
                })
                .collect(Collectors.toList());
        System.out.printf("② 自定義排序: %s%n", orderDescList);
    }

    /*
    4.distinct():用於去除 Stream 中重複的元素,確保最終的 Stream 中每個元素都是唯一的。
    */
    @Test
    void distinctTest() {
        List<Integer> numList = Arrays.asList(1,1,1,1,2,3,2,2);
        List<Integer> distinctList = numList.stream()
                .distinct()
                .collect(Collectors.toList());
        System.out.println(distinctList);
    }

    /*
   5.limit(long n):用於限制Stream的大小,返回一個最大包含前n個元素的新Stream。
   */
    @Test
    void limitTest() {
        List<Integer> numList = Arrays.asList(1,2,3,4,5,6,7,8);
        List<Integer> limitList = numList.stream()
                .limit(4)
                .collect(Collectors.toList());
        System.out.println(limitList);
    }

    /*
    6.skip(long n):用於跳過Stream中的前n個元素,返回一個丟棄了前n個元素後剩餘元素的新Stream。
    */
    @Test
    void skipTest() {
        List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
        List<Integer> skipList = numList.stream()
                .skip(numList.size() - 2)
                .collect(Collectors.toList());
        System.out.println(skipList);
    }

    /*
    7.forEach(Consumer):對Stream中的每個元素執行指定的操作,接收一個Consumer(消費者函式)作為引數。它通常用於對Stream中的元素進行輸出或執行某些操作,但不會返回任何結果。
    */
    @Test
    void forEachTest() {
        // 給公司工資普漲 500
        List<Integer> salaryList = Arrays.asList(12000, 20000, 30000, 4000);
        salaryList.stream()
                .map(s -> s + 500)
                .forEach(s -> {
                    System.out.println("--工資普漲後:" + s);
                });
    }

    /*
    8.collect(Collector):用於將Stream中的元素收集到一個容器中,接收一個Collector(收集器)作為引數。它允許你在Stream中執行各種集合操作,
    例如將元素收集到List、Set、Map等容器中。

    如下程式碼的含義是建立一個人員集合,透過 stream() 轉換為 Stream 流,使用 collect() 方法把元素歸集,
    利用 Collectors.toMap() 收集器轉換為 Map 後,內部接收會遍歷每個元素,Collectors.toMap(User::getName, User::getSalary)是簡寫,
    詳細的寫法如下:Collectors.toMap(s -> s.getName(), s -> s.getSalary())
    */
    @Test
    void collectTest() {
        List<User> userList = Arrays.asList(new User("張三", 2000.5),
                new User("李斯", 11000.5),
                new User("王二", 12000.5),
                new User("張六", 32000.5),
                new User("趙公子", 1000000.0));
        Map<String, Double> userSalaryMap = userList.stream()
                .collect(Collectors.toMap(User::getName, User::getSalary));
        userSalaryMap.forEach((k, v) -> {
            System.out.printf("姓名:%s,工資:%.2f%n", k, v);
        });
    }

    /*
    9.anyMatch(Predicate) / allMatch(Predicate) / noneMatch(Predicate)
    Stream 類的 anyMatch(), allMatch(), 和 noneMatch() 是用於檢查流中元素是否滿足特定條件的終端操作。
    它們返回一個布林值,表示流中的元素是否滿足指定的條件。這些方法在遇到滿足條件的元素後可能會提前終止流的處理。
    anyMatch檢查是否有任意元素滿足條件,allMatch檢查是否所有元素都滿足條件,noneMatch檢查是否沒有元素滿足條件。
    */
    @Test
    void MatchTest() {
        // 示例整數流
        Stream<Integer> integerStream = Stream.of(1, 5, 3, 8, 2);

        // 使用anyMatch()檢查是否存在元素大於5
        boolean anyGreaterThan5 = integerStream.anyMatch(num -> num > 5);
        System.out.println("是否存在元素大於 5 ?" + anyGreaterThan5);

        // 重新建立一個整數流,因為流已被消耗
        Stream<Integer> newIntegerStream = Stream.of(1, 5, 3, 8, 2);

        // 使用allMatch()檢查是否所有元素都小於10
        boolean allLessThan10 = newIntegerStream.allMatch(num -> num < 10);
        System.out.println("所有元素都小於10 ? " + allLessThan10);

        // 重新建立一個整數流,因為流已被消耗
        Stream<Integer> newestIntegerStream = Stream.of(1, 5, 3, 8, 2);

        // 使用noneMatch()檢查是否沒有元素等於10
        boolean noneEqualTo10 = newestIntegerStream.noneMatch(num -> num == 10);
        System.out.println("是否沒有元素等於 10 ? " + noneEqualTo10);
    }


    /*
   10.findFirst() / findAny()
        Stream 類的 findFirst() 和 findAny()
        方法用於在流中查詢元素的終端操作。它們都返回一個 Optional 物件,表示找到的元素或元素的可能性。
   */
    @Test
    void findTest() {
        // 示例整數流
        Stream<Integer> integerStream = Stream.of(1, 5, 3, 8, 2);

        // 使用findFirst()找到第一個元素
        Optional<Integer> firstElementOptional = integerStream.findFirst();
        System.out.println("發現第一個元素: " + firstElementOptional.get());

        //isPresent() 判斷流是否為null
        if (firstElementOptional.isPresent()) {
            System.out.println("發現第一個元素: " + firstElementOptional.get());
        } else {
            System.out.println("流為空!");
        }

         // 使用findAny()找到任意一個元素
        Stream<Integer> stream = Stream.of(1, 2, 3);
        Optional<Integer> any = stream.findAny();
        System.out.println("找到任意一個元素: " +any.get());
        // 資料說:可能輸出 1、2 或 3 但實際操作每次都輸出1

    }


}

package com.example.demo;

public class User {
    private String name;
    private Double salary;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    public User(String name, Double salary) {
        this.name = name;
        this.salary = salary;
    }
}

相關文章