欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?Stream?流基本概念和使用方式詳解

 更新時(shí)間:2025年09月02日 09:43:02   作者:MadeInSQL  
Stream是Java 8 引入的全新API,它基于函數(shù)式編程思想,為集合操作提供了一種聲明式的處理方式,本文給大家介紹Java Stream流基本概念和核心特性,感興趣的朋友一起看看吧

一、Stream 基礎(chǔ)概念與核心特性

1.1 什么是 Stream 流

Stream 是 Java 8 引入的全新API,它基于函數(shù)式編程思想,為集合操作提供了一種聲明式的處理方式。與傳統(tǒng)的命令式集合操作不同,Stream API 使得數(shù)據(jù)處理更加高效且易于并行化。

核心特點(diǎn)詳解:

  • 惰性求值(Lazy Evaluation):
    • 中間操作(如 filter、map)不會(huì)立即執(zhí)行
    • 只有遇到終止操作(如 collect、forEach)時(shí)才會(huì)觸發(fā)計(jì)算
    • 示例:list.stream().filter(x -> x > 10).count()中,filter 操作在 count 被調(diào)用時(shí)才執(zhí)行
  • 不可復(fù)用(Single Use):
    • 每個(gè) Stream 管道(pipeline)只能被消費(fèi)一次
    • 重復(fù)使用會(huì)拋出 IllegalStateException
    • 解決方案:每次需要時(shí)重新創(chuàng)建 Stream
  • 內(nèi)部迭代(Internal Iteration):
    • 不需要顯式編寫 for/while 循環(huán)
    • 迭代過程由 Stream API 內(nèi)部處理
    • 對(duì)比:傳統(tǒng) for 循環(huán)是外部迭代
  • 函數(shù)式風(fēng)格(Functional Style):
    • 支持 Lambda 表達(dá)式(如 x -> x*2)
    • 支持方法引用(如 String::length)
    • 無副作用:理想情況下不修改外部狀態(tài)

典型使用場景:

  • 數(shù)據(jù)篩選過濾(filter)
  • 數(shù)據(jù)轉(zhuǎn)換映射(map)
  • 聚合計(jì)算(reduce、collect)
  • 并行數(shù)據(jù)處理(parallelStream)

示例代碼:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 傳統(tǒng)方式
for(String name : names) {
    if(name.startsWith("A")) {
        System.out.println(name.toUpperCase());
    }
}
// Stream方式
names.stream()
     .filter(name -> name.startsWith("A"))
     .map(String::toUpperCase)
     .forEach(System.out::println);

1.2 Stream 與集合的區(qū)別

特性集合(Collection)Stream(流)
存儲(chǔ)存儲(chǔ)實(shí)際數(shù)據(jù)不存儲(chǔ)數(shù)據(jù)
操作方式外部迭代(foreach循環(huán))內(nèi)部迭代
數(shù)據(jù)處理立即執(zhí)行延遲執(zhí)行
可重用性可多次遍歷只能遍歷一次
并行能力需要手動(dòng)實(shí)現(xiàn)內(nèi)置并行支持

二、Stream 創(chuàng)建方式詳解

2.1 從集合創(chuàng)建

// 從List創(chuàng)建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream1 = list.stream();
// 從Set創(chuàng)建
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3));
Stream<Integer> stream2 = set.stream();

2.2 從數(shù)組創(chuàng)建

String[] array = {"a", "b", "c"};
Stream<String> stream3 = Arrays.stream(array);
// 指定范圍
Stream<String> stream4 = Arrays.stream(array, 1, 3); // "b", "c"

2.3 使用靜態(tài)工廠方法

// 使用Stream.of()
Stream<String> stream5 = Stream.of("a", "b", "c");
// 創(chuàng)建空流
Stream<String> emptyStream = Stream.empty();
// 創(chuàng)建無限流
Stream<Integer> infiniteStream1 = Stream.iterate(0, n -> n + 2); // 0,2,4,6...
Stream<Double> infiniteStream2 = Stream.generate(Math::random); // 隨機(jī)數(shù)流

2.4 其他創(chuàng)建方式

// 從文件創(chuàng)建
try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) {
    lines.forEach(System.out::println);
}
// 從字符串創(chuàng)建
IntStream charStream = "Hello".chars();

三、Stream 核心操作全解析

3.1 中間操作(Intermediate Operations)

過濾操作

// filter() - 篩選偶數(shù)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evens = numbers.stream()
                           .filter(n -> n % 2 == 0)
                           .collect(Collectors.toList()); // [2, 4]
// distinct() - 去重
List<String> names = Arrays.asList("John", "John", "Mary");
List<String> uniqueNames = names.stream()
                              .distinct()
                              .collect(Collectors.toList()); // ["John", "Mary"]

映射操作

// map() - 字符串轉(zhuǎn)大寫
List<String> upperNames = names.stream()
                             .map(String::toUpperCase)
                             .collect(Collectors.toList());
// flatMap() - 扁平化處理
List<List<String>> nestedList = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d")
);
List<String> flatList = nestedList.stream()
                                .flatMap(Collection::stream)
                                .collect(Collectors.toList()); // ["a", "b", "c", "d"]

限制與跳過

// limit() - 限制數(shù)量
List<Integer> limited = numbers.stream()
                             .limit(3)
                             .collect(Collectors.toList()); // [1, 2, 3]
// skip() - 跳過元素
List<Integer> skipped = numbers.stream()
                            .skip(2)
                            .collect(Collectors.toList()); // [3, 4, 5]

排序操作

// sorted() - 自然排序
List<String> sortedNames = names.stream()
                              .sorted()
                              .collect(Collectors.toList());
// sorted(Comparator) - 自定義排序
List<Person> people = Arrays.asList(
    new Person("John", 25),
    new Person("Mary", 20)
);
List<Person> sortedByAge = people.stream()
                               .sorted(Comparator.comparing(Person::getAge))
                               .collect(Collectors.toList());

3.2 終端操作(Terminal Operations)

匹配與查找

// anyMatch() - 是否有元素匹配
boolean hasEven = numbers.stream()
                       .anyMatch(n -> n % 2 == 0); // true
// findFirst() - 獲取第一個(gè)元素
Optional<Integer> first = numbers.stream()
                               .findFirst(); // Optional[1]

聚合操作

// count() - 計(jì)數(shù)
long count = numbers.stream().count(); // 5
// max()/min() - 最大最小值
Optional<Integer> max = numbers.stream()
                             .max(Integer::compare); // Optional[5]
// reduce() - 歸約操作
Optional<Integer> sum = numbers.stream()
                             .reduce(Integer::sum); // Optional[15]

收集操作

// collect() - 轉(zhuǎn)換為集合
Set<Integer> numberSet = numbers.stream()
                              .collect(Collectors.toSet());
// joining() - 字符串連接
String joined = names.stream()
                   .collect(Collectors.joining(", ")); // "John, John, Mary"
// groupingBy() - 分組
Map<Integer, List<Person>> peopleByAge = people.stream()
                                             .collect(Collectors.groupingBy(Person::getAge));

遍歷操作

// forEach() - 遍歷消費(fèi)
numbers.stream().forEach(System.out::println);
// forEachOrdered() - 保證順序
numbers.parallelStream().forEachOrdered(System.out::println);

四、并行流與性能優(yōu)化

4.1 并行流基礎(chǔ)

// 創(chuàng)建并行流
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 方式1:從集合創(chuàng)建
Stream<Integer> parallelStream1 = numbers.parallelStream();
// 方式2:將順序流轉(zhuǎn)并行
Stream<Integer> parallelStream2 = numbers.stream().parallel();
// 示例:并行處理
long count = numbers.parallelStream()
                  .filter(n -> n % 2 == 0)
                  .count();

4.2 性能考量

適合使用并行流的場景

  • 數(shù)據(jù)量較大(通常超過1萬元素)
  • 單個(gè)元素處理耗時(shí)較長
  • 操作是無狀態(tài)的(不依賴之前處理的結(jié)果)
  • 操作不要求順序

注意事項(xiàng)

  • 并行化本身有開銷,小數(shù)據(jù)集可能更慢
  • 確保線程安全,避免共享可變狀態(tài)
  • 考慮使用unordered()去除順序約束提升性能

4.3 自定義線程池

// 使用自定義ForkJoinPool
ForkJoinPool customPool = new ForkJoinPool(4);
long result = customPool.submit(() -> 
    numbers.parallelStream()
         .filter(n -> n % 2 == 0)
         .count()
).get();

五、實(shí)戰(zhàn)應(yīng)用案例

5.1 數(shù)據(jù)處理案例

// 案例1:統(tǒng)計(jì)單詞頻率
List<String> words = Arrays.asList("hello", "world", "hello", "java");
Map<String, Long> wordCounts = words.stream()
                                  .collect(Collectors.groupingBy(
                                      Function.identity(),
                                      Collectors.counting()
                                  ));
// 案例2:多級(jí)分組
List<Employee> employees = ...;
Map<String, Map<String, List<Employee>>> byDeptAndCity = employees.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment,
             Collectors.groupingBy(Employee::getCity)));

5.2 文件處理案例

// 讀取文件并處理
try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) {
    List<String> filteredLines = lines
        .filter(line -> !line.startsWith("#")) // 過濾注釋行
        .map(String::trim)                     // 去除空格
        .collect(Collectors.toList());
}
// 查找文件中最長的行
Optional<String> longest = Files.lines(Paths.get("data.txt"))
    .max(Comparator.comparing(String::length));

5.3 數(shù)據(jù)庫查詢結(jié)果處理

// 使用Stream處理JDBC結(jié)果
List<Person> persons = new ArrayList<>();
try (Connection conn = DriverManager.getConnection(url, user, pass);
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery("SELECT * FROM persons")) {
    Stream<ResultSet> stream = StreamSupport.stream(
        new Spliterators.AbstractSpliterator<ResultSet>(
            Long.MAX_VALUE, Spliterator.ORDERED) {
            public boolean tryAdvance(Consumer<? super ResultSet> action) {
                try {
                    if (!rs.next()) return false;
                    action.accept(rs);
                    return true;
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }, false);
    persons = stream.map(rs -> new Person(rs.getString("name"), rs.getInt("age")))
                   .collect(Collectors.toList());
}

六、常見問題與最佳實(shí)踐

6.1 常見陷阱

  1. 重復(fù)使用Stream

    Stream<String> stream = Stream.of("a", "b", "c");
    stream.forEach(System.out::println);
    stream.forEach(System.out::println); // 拋出IllegalStateException
    
  2. 修改源集合

    List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
    Stream<String> stream = list.stream();
    list.add("d"); // 可能導(dǎo)致ConcurrentModificationException
    
  3. 無限流未限制

    Stream.iterate(0, i -> i + 1)
        .forEach(System.out::println); // 無限循環(huán)
    

6.2 性能優(yōu)化建議

  1. 優(yōu)先使用基本類型流

    // 使用IntStream代替Stream<Integer>
    IntStream.range(0, 100).sum();
    
  2. 短路操作優(yōu)化

    // 使用anyMatch代替filter+findFirst
    boolean hasNegative = numbers.stream().anyMatch(n -> n < 0);
    
  3. 合并中間操作

    // 合并多個(gè)filter
    list.stream().filter(s -> s != null && s.length() > 3);
    

6.3 調(diào)試技巧

  1. 使用peek()調(diào)試

    List<String> result = list.stream()
        .peek(System.out::println)  // 調(diào)試輸出
        .filter(s -> s.length() > 3)
        .peek(System.out::println)  // 調(diào)試輸出
        .collect(Collectors.toList());
    
  2. 轉(zhuǎn)換為并行流查找問題

    list.stream()
        .parallel()
        .map(s -> {throw new RuntimeException();}) // 更容易暴露線程安全問題
        .collect(Collectors.toList());
    

七、高級(jí)特性與未來展望

7.1 Java 9+ 增強(qiáng)特性

// takeWhile/dropWhile (Java 9+)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 3, 2, 1);
List<Integer> taken = numbers.stream()
                           .takeWhile(n -> n < 4) // [1, 2, 3]
                           .collect(Collectors.toList());
// ofNullable (Java 9+)
Stream<String> stream = Stream.ofNullable(System.getProperty("key"));
// iterate增強(qiáng) (Java 9+)
Stream.iterate(0, n -> n < 10, n -> n + 1) // 類似for循環(huán)
      .forEach(System.out::println);

7.2 響應(yīng)式編程結(jié)合

// 與RxJava/Reactor結(jié)合示例
Flux.fromStream(Stream.generate(() -> "data"))
    .delayElements(Duration.ofMillis(100))
    .take(10)
    .subscribe(System.out::println);

7.3 未來發(fā)展方向

  1. 值類型流:對(duì)基本類型更高效的支持
  2. 模式匹配:增強(qiáng)流處理表達(dá)能力
  3. 更強(qiáng)大的收集器:提供更多內(nèi)置收集操作

到此這篇關(guān)于Java Stream 流詳解的文章就介紹到這了,更多相關(guān)Java Stream 流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

到此這篇關(guān)于Java Stream 流基本概念和使用方式詳解的文章就介紹到這了,更多相關(guān)Java Stream 流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于java中多個(gè)JDK和切換版本介紹

    關(guān)于java中多個(gè)JDK和切換版本介紹

    大家好,本篇文章主要講的是關(guān)于java中多個(gè)JDK和切換版本介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • 在SpringBoot中配置和使用多個(gè)數(shù)據(jù)源方式

    在SpringBoot中配置和使用多個(gè)數(shù)據(jù)源方式

    本文介紹如何在Spring?Boot中配置多數(shù)據(jù)源,需通過配置類聲明不同數(shù)據(jù)源bean,使用@ConfigurationProperties映射屬性,并針對(duì)SpringDataJDBC和JPA分別配置JdbcTemplate與EntityManagerFactory,注意拆分包及@Primary注解的使用,同時(shí)可配置Hikari連接池
    2025-08-08
  • java的五種數(shù)據(jù)類型解析

    java的五種數(shù)據(jù)類型解析

    下面小編就為大家?guī)硪黄猨ava的五種數(shù)據(jù)類型解析。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-05-05
  • 解決Springboot集成Redis集群配置公網(wǎng)IP連接報(bào)私網(wǎng)IP連接失敗問題

    解決Springboot集成Redis集群配置公網(wǎng)IP連接報(bào)私網(wǎng)IP連接失敗問題

    在Springboot 集成 Redis集群配置公網(wǎng)IP連接報(bào)私網(wǎng)IP連接失敗,一直報(bào)私有IP連接失敗,所以本文小編給大家介紹了如何解決報(bào)錯(cuò)問題,如果有遇到相同問題的同學(xué),可以參考閱讀本文
    2023-10-10
  • 如何查找YUM安裝的JAVA_HOME環(huán)境變量詳解

    如何查找YUM安裝的JAVA_HOME環(huán)境變量詳解

    這篇文章主要給大家介紹了關(guān)于如何查找YUM安裝的JAVA_HOME環(huán)境變量的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • MyBatis中resultMap和resultType的區(qū)別詳解

    MyBatis中resultMap和resultType的區(qū)別詳解

    這篇文章主要介紹了MyBatis中resultMap和resultType的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 淺談slf4j中的橋接器是如何運(yùn)作的

    淺談slf4j中的橋接器是如何運(yùn)作的

    這篇文章主要介紹了slf4j中的橋接器是如何運(yùn)作的,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • MyBatis批量插入數(shù)據(jù)到Oracle數(shù)據(jù)庫中的兩種方式(實(shí)例代碼)

    MyBatis批量插入數(shù)據(jù)到Oracle數(shù)據(jù)庫中的兩種方式(實(shí)例代碼)

    本文通過實(shí)例代碼給大家分享了MyBatis批量插入數(shù)據(jù)到Oracle數(shù)據(jù)庫中的兩種方式,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-09-09
  • java中把字符串轉(zhuǎn)成 double的方法

    java中把字符串轉(zhuǎn)成 double的方法

    Java 中可以使用 Double 類中的靜態(tài)方法 parseDouble() 將一個(gè)字符串轉(zhuǎn)換為 double 類型的數(shù)值,本文結(jié)合實(shí)例代碼對(duì)java字符串轉(zhuǎn)成 double詳細(xì)講解,需要的朋友參考下吧
    2023-08-08
  • Java入門基礎(chǔ)之常規(guī)的命名方法和變量的值及其引用

    Java入門基礎(chǔ)之常規(guī)的命名方法和變量的值及其引用

    這篇文章主要介紹了Java的命名方法和變量的值及其引用,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09

最新評(píng)論