最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Stream流從入門到精通

 更新時間:2025年11月11日 15:08:17   作者:待畔逢  
Stream(流)是Java 8引入的一個重要特性,它提供了一種聲明式的數(shù)據(jù)處理方式,本文給大家介紹Java Stream流從入門到精通,感興趣的朋友跟隨小編一起看看吧

Java Stream流詳解:從入門到精通

1. Stream流簡介

什么是Stream?

Stream(流)是Java 8引入的一個重要特性,它提供了一種聲明式的數(shù)據(jù)處理方式。Stream不是數(shù)據(jù)結(jié)構(gòu),而是對數(shù)據(jù)源(如集合、數(shù)組等)進(jìn)行操作的抽象。

為什么要使用Stream?

傳統(tǒng)的集合操作往往需要編寫大量的循環(huán)代碼,而Stream提供了更加簡潔、易讀的函數(shù)式編程風(fēng)格:

// 傳統(tǒng)方式:找出年齡大于18的用戶姓名
List<String> result = new ArrayList<>();
for (User user : users) {
    if (user.getAge() > 18) {
        result.add(user.getName());
    }
}
// Stream方式
List<String> result = users.stream()
    .filter(user -> user.getAge() > 18)
    .map(User::getName)
    .collect(Collectors.toList());

2. Stream的特點

2.1 主要特征

  1. 不存儲數(shù)據(jù):Stream不是數(shù)據(jù)結(jié)構(gòu),不會存儲元素
  2. 函數(shù)式編程:支持鏈?zhǔn)秸{(diào)用,代碼更簡潔
  3. 惰性求值:中間操作不會立即執(zhí)行,只有遇到終端操作才會執(zhí)行
  4. 可消費性:Stream只能被消費一次

2.2 Stream操作分類

// 中間操作(Intermediate Operations)
// 返回Stream對象,支持鏈?zhǔn)秸{(diào)用
stream.filter().map().sorted()
// 終端操作(Terminal Operations)  
// 返回具體結(jié)果,觸發(fā)流的執(zhí)行
stream.collect().forEach().reduce()

3. 創(chuàng)建Stream流

3.1 從集合創(chuàng)建

List<String> list = Arrays.asList("a", "b", "c");
// 串行流
Stream<String> stream = list.stream();
// 并行流
Stream<String> parallelStream = list.parallelStream();

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

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

3.3 直接創(chuàng)建

// 通過Stream.of()
Stream<String> stream = Stream.of("a", "b", "c");
// 創(chuàng)建空流
Stream<String> empty = Stream.empty();
// 創(chuàng)建無限流
Stream<Integer> iterate = Stream.iterate(0, n -> n + 2);
Stream<Double> generate = Stream.generate(Math::random);

3.4 從文件創(chuàng)建

try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
    lines.forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}

4. 中間操作詳解

4.1 filter() - 過濾

根據(jù)條件過濾元素:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 過濾出偶數(shù)
List<Integer> evenNumbers = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());
// 結(jié)果:[2, 4, 6, 8, 10]

4.2 map() - 映射轉(zhuǎn)換

將元素轉(zhuǎn)換為其他形式:

List<String> words = Arrays.asList("hello", "world", "java");
// 轉(zhuǎn)換為大寫
List<String> upperCase = words.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());
// 結(jié)果:["HELLO", "WORLD", "JAVA"]
// 獲取字符串長度
List<Integer> lengths = words.stream()
    .map(String::length)
    .collect(Collectors.toList());
// 結(jié)果:[5, 5, 4]

4.3 flatMap() - 扁平化映射

將嵌套結(jié)構(gòu)扁平化:

List<List<String>> nested = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d"),
    Arrays.asList("e", "f")
);
// 扁平化處理
List<String> flattened = nested.stream()
    .flatMap(Collection::stream)
    .collect(Collectors.toList());
// 結(jié)果:["a", "b", "c", "d", "e", "f"]

4.4 distinct() - 去重

List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 4, 5);
List<Integer> unique = numbers.stream()
    .distinct()
    .collect(Collectors.toList());
// 結(jié)果:[1, 2, 3, 4, 5]

4.5 sorted() - 排序

List<String> words = Arrays.asList("banana", "apple", "cherry");
// 自然排序
List<String> sorted = words.stream()
    .sorted()
    .collect(Collectors.toList());
// 結(jié)果:["apple", "banana", "cherry"]
// 自定義排序
List<String> sortedByLength = words.stream()
    .sorted(Comparator.comparing(String::length))
    .collect(Collectors.toList());
// 結(jié)果:["apple", "banana", "cherry"]

4.6 limit() 和 skip()

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 限制元素數(shù)量
List<Integer> limited = numbers.stream()
    .limit(5)
    .collect(Collectors.toList());
// 結(jié)果:[1, 2, 3, 4, 5]
// 跳過前幾個元素
List<Integer> skipped = numbers.stream()
    .skip(5)
    .collect(Collectors.toList());
// 結(jié)果:[6, 7, 8, 9, 10]
// 分頁效果:跳過前5個,取3個
List<Integer> page = numbers.stream()
    .skip(5)
    .limit(3)
    .collect(Collectors.toList());
// 結(jié)果:[6, 7, 8]

5. 終端操作詳解

5.1 collect() - 收集結(jié)果

List<String> words = Arrays.asList("apple", "banana", "cherry");
// 收集到List
List<String> list = words.stream().collect(Collectors.toList());
// 收集到Set
Set<String> set = words.stream().collect(Collectors.toSet());
// 收集到Map
Map<String, Integer> map = words.stream()
    .collect(Collectors.toMap(
        word -> word,           // key
        String::length          // value
    ));
// 分組
Map<Integer, List<String>> grouped = words.stream()
    .collect(Collectors.groupingBy(String::length));
// 連接字符串
String joined = words.stream()
    .collect(Collectors.joining(", "));
// 結(jié)果:"apple, banana, cherry"

5.2 forEach() - 遍歷

List<String> words = Arrays.asList("apple", "banana", "cherry");
// 打印每個元素
words.stream().forEach(System.out::println);
// 并行遍歷(注意:順序不保證)
words.parallelStream().forEach(System.out::println);
// 有序遍歷
words.parallelStream().forEachOrdered(System.out::println);

5.3 reduce() - 歸約

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 求和
Optional<Integer> sum = numbers.stream()
    .reduce((a, b) -> a + b);
// 帶初始值的求和
Integer sum2 = numbers.stream()
    .reduce(0, (a, b) -> a + b);
// 求最大值
Optional<Integer> max = numbers.stream()
    .reduce(Integer::max);
// 字符串連接
List<String> words = Arrays.asList("Hello", " ", "World");
String result = words.stream()
    .reduce("", String::concat);
// 結(jié)果:"Hello World"

5.4 查找操作

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 查找任意一個偶數(shù)
Optional<Integer> any = numbers.stream()
    .filter(n -> n % 2 == 0)
    .findAny();
// 查找第一個偶數(shù)
Optional<Integer> first = numbers.stream()
    .filter(n -> n % 2 == 0)
    .findFirst();

5.5 匹配操作

List<Integer> numbers = Arrays.asList(2, 4, 6, 8);
// 是否所有元素都是偶數(shù)
boolean allEven = numbers.stream()
    .allMatch(n -> n % 2 == 0);  // true
// 是否存在偶數(shù)
boolean anyEven = numbers.stream()
    .anyMatch(n -> n % 2 == 0);  // true
// 是否沒有奇數(shù)
boolean noneOdd = numbers.stream()
    .noneMatch(n -> n % 2 == 1); // true

5.6 統(tǒng)計操作

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 計數(shù)
long count = numbers.stream().count();
// 數(shù)值流統(tǒng)計
IntSummaryStatistics stats = numbers.stream()
    .mapToInt(Integer::intValue)
    .summaryStatistics();
System.out.println("Count: " + stats.getCount());
System.out.println("Sum: " + stats.getSum());
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());

6. 實際應(yīng)用案例

6.1 用戶數(shù)據(jù)處理

public class User {
    private String name;
    private int age;
    private String city;
    private double salary;
    // 構(gòu)造函數(shù)、getter、setter省略
}
List<User> users = Arrays.asList(
    new User("張三", 25, "北京", 8000),
    new User("李四", 30, "上海", 12000),
    new User("王五", 22, "北京", 6000),
    new User("趙六", 28, "深圳", 15000)
);
// 案例1:找出年齡大于25歲,在北京工作的用戶姓名
List<String> result1 = users.stream()
    .filter(user -> user.getAge() > 25)
    .filter(user -> "北京".equals(user.getCity()))
    .map(User::getName)
    .collect(Collectors.toList());
// 案例2:按城市分組統(tǒng)計平均工資
Map<String, Double> avgSalaryByCity = users.stream()
    .collect(Collectors.groupingBy(
        User::getCity,
        Collectors.averagingDouble(User::getSalary)
    ));
// 案例3:找出工資最高的用戶
Optional<User> highestPaid = users.stream()
    .max(Comparator.comparing(User::getSalary));
// 案例4:計算所有用戶的總工資
double totalSalary = users.stream()
    .mapToDouble(User::getSalary)
    .sum();

6.2 文件處理

// 讀取文件并統(tǒng)計單詞頻率
public Map<String, Long> countWords(String filePath) {
    try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
        return lines
            .flatMap(line -> Arrays.stream(line.split("\\s+")))
            .filter(word -> !word.isEmpty())
            .map(String::toLowerCase)
            .collect(Collectors.groupingBy(
                Function.identity(),
                Collectors.counting()
            ));
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

6.3 數(shù)據(jù)轉(zhuǎn)換

// 將CSV數(shù)據(jù)轉(zhuǎn)換為對象
public List<Product> parseCSV(List<String> csvLines) {
    return csvLines.stream()
        .skip(1) // 跳過標(biāo)題行
        .map(line -> line.split(","))
        .filter(fields -> fields.length >= 3)
        .map(fields -> new Product(
            fields[0].trim(),
            Double.parseDouble(fields[1].trim()),
            Integer.parseInt(fields[2].trim())
        ))
        .collect(Collectors.toList());
}

7. 性能優(yōu)化建議

7.1 選擇合適的流類型

// 對于大數(shù)據(jù)集,考慮使用并行流
List<Integer> largeList = IntStream.range(0, 1000000)
    .boxed()
    .collect(Collectors.toList());
// 串行流
long serialTime = System.currentTimeMillis();
long serialSum = largeList.stream()
    .mapToLong(Integer::longValue)
    .sum();
serialTime = System.currentTimeMillis() - serialTime;
// 并行流
long parallelTime = System.currentTimeMillis();
long parallelSum = largeList.parallelStream()
    .mapToLong(Integer::longValue)
    .sum();
parallelTime = System.currentTimeMillis() - parallelTime;

7.2 避免裝箱拆箱

// 不推薦:會產(chǎn)生裝箱拆箱開銷
int sum1 = numbers.stream()
    .mapToInt(Integer::intValue)
    .sum();
// 推薦:直接使用基本類型流
int sum2 = IntStream.of(1, 2, 3, 4, 5).sum();

7.3 合理使用短路操作

// 使用短路操作提高效率
boolean hasEven = numbers.stream()
    .anyMatch(n -> n % 2 == 0); // 找到第一個偶數(shù)就返回
// 限制處理數(shù)量
List<String> first10 = largeStringList.stream()
    .filter(s -> s.length() > 5)
    .limit(10)
    .collect(Collectors.toList());

8. 常見陷阱與注意事項

8.1 Stream只能使用一次

Stream<String> stream = Stream.of("a", "b", "c");
stream.forEach(System.out::println); // 正常
// stream.count(); // 拋出IllegalStateException

8.2 并行流的線程安全

// 錯誤:非線程安全的操作
List<String> result = new ArrayList<>();
words.parallelStream().forEach(result::add); // 可能導(dǎo)致數(shù)據(jù)丟失
// 正確:使用線程安全的收集器
List<String> result = words.parallelStream()
    .collect(Collectors.toList());

8.3 注意null值處理

List<String> words = Arrays.asList("hello", null, "world");
// 過濾null值
List<String> filtered = words.stream()
    .filter(Objects::nonNull)
    .collect(Collectors.toList());

9. 總結(jié)

Stream流是Java 8引入的強大特性,它提供了:

優(yōu)點

  • 簡潔性:減少樣板代碼,提高代碼可讀性
  • 函數(shù)式編程:支持鏈?zhǔn)秸{(diào)用,代碼更優(yōu)雅
  • 并行處理:輕松實現(xiàn)并行計算
  • 惰性求值:提高性能,按需計算

適用場景

  • 集合數(shù)據(jù)的過濾、轉(zhuǎn)換、聚合
  • 大數(shù)據(jù)集的并行處理
  • 復(fù)雜的數(shù)據(jù)查詢和統(tǒng)計
  • 函數(shù)式編程風(fēng)格的代碼

最佳實踐

  1. 優(yōu)先使用Stream API替代傳統(tǒng)循環(huán)
  2. 合理選擇串行流和并行流
  3. 注意Stream的一次性使用特性
  4. 使用基本類型流避免裝箱開銷
  5. 善用短路操作提高性能

通過掌握Stream流,你可以寫出更加簡潔、高效、易維護(hù)的Java代碼。在實際開發(fā)中,Stream已經(jīng)成為處理集合數(shù)據(jù)的標(biāo)準(zhǔn)方式,值得每個Java開發(fā)者深入學(xué)習(xí)和應(yīng)用。

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

相關(guān)文章

  • Java Calendar類使用案例詳解

    Java Calendar類使用案例詳解

    這篇文章主要介紹了Java Calendar類使用案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • IntelliJ IDEA連接MySQL數(shù)據(jù)庫詳細(xì)圖解

    IntelliJ IDEA連接MySQL數(shù)據(jù)庫詳細(xì)圖解

    今天小編就為大家分享一篇關(guān)于intellij idea連接mysql數(shù)據(jù)庫詳細(xì)圖解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • 如何解決HttpServletRequest.getInputStream()多次讀取問題

    如何解決HttpServletRequest.getInputStream()多次讀取問題

    這篇文章主要介紹了如何解決HttpServletRequest.getInputStream()多次讀取問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java中2個對象字段值比較是否相同

    Java中2個對象字段值比較是否相同

    本文主要介紹了Java中2個對象字段值比較是否相同,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • java隨機生成一個名字和對應(yīng)拼音的方法

    java隨機生成一個名字和對應(yīng)拼音的方法

    這篇文章主要介紹了java隨機生成一個名字和對應(yīng)拼音的方法,涉及java針對數(shù)組及隨機數(shù)操作的相關(guān)技巧,需要的朋友可以參考下
    2015-07-07
  • Java 利用遞歸實現(xiàn)鏈表的歸并排序

    Java 利用遞歸實現(xiàn)鏈表的歸并排序

    這篇文章主要介紹了Java 如何利用遞歸實現(xiàn)鏈表的歸并排序,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-09-09
  • Java實現(xiàn)的n階曲線擬合功能示例

    Java實現(xiàn)的n階曲線擬合功能示例

    這篇文章主要介紹了Java實現(xiàn)的n階曲線擬合功能,結(jié)合實例形式分析了Java基于矩陣的多項式曲線擬合相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • Java實現(xiàn)重定向過程中添加請求頭信息

    Java實現(xiàn)重定向過程中添加請求頭信息

    在Java中,我們經(jīng)常需要使用網(wǎng)絡(luò)請求來與服務(wù)器進(jìn)行通信,在進(jìn)行網(wǎng)絡(luò)請求時,有時我們需要在重定向過程中添加請求頭信息,本文將介紹如何使用Java在重定向過程中添加請求頭,并提供相應(yīng)的代碼示例,
    2023-10-10
  • 淺談Java實現(xiàn)分布式事務(wù)的三種方案

    淺談Java實現(xiàn)分布式事務(wù)的三種方案

    現(xiàn)在互聯(lián)網(wǎng)下,分布式和微服務(wù)橫行,難免會遇到分布式下的事務(wù)問題,當(dāng)然微服務(wù)下可能沒有分布式事務(wù),但是很多場景是需要分布式事務(wù)的。下面就來介紹下什么是分布式事務(wù)和分布式事務(wù)的解決方案
    2021-06-06
  • java日期操作工具類(獲取指定日期、日期轉(zhuǎn)換、相隔天數(shù))

    java日期操作工具類(獲取指定日期、日期轉(zhuǎn)換、相隔天數(shù))

    這篇文章主要為大家詳細(xì)介紹了java日期操作工具類,包括獲取指定日期、日期轉(zhuǎn)換、相隔天數(shù)等操作,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評論

昌图县| 西昌市| 张家口市| 平塘县| 婺源县| 敖汉旗| 株洲市| 车致| 兴化市| 潮州市| 盖州市| 六枝特区| 高台县| 秦安县| 青河县| 花莲县| 灯塔市| 鄂尔多斯市| 台东市| 麟游县| 侯马市| 宁武县| 宁城县| 平凉市| 渑池县| 五大连池市| 云阳县| 兰溪市| 阿荣旗| 开封县| 杭锦旗| 兰溪市| 剑河县| 马龙县| 仙居县| 台湾省| 从化市| 临漳县| 丁青县| 莆田市| 蕉岭县|