java的Stream流處理示例小結(jié)
Java Stream 流處理詳解
Stream 是 Java 8 引入的一個(gè)強(qiáng)大的數(shù)據(jù)處理抽象,它允許你以聲明式方式處理數(shù)據(jù)集合(類似于 SQL 語(yǔ)句),支持并行操作,提高了代碼的可讀性和處理效率。
一、Stream 的核心概念
1. 什么是 Stream
- 不是數(shù)據(jù)結(jié)構(gòu):不存儲(chǔ)數(shù)據(jù),只是從數(shù)據(jù)源(集合、數(shù)組等)獲取數(shù)據(jù)
- 函數(shù)式風(fēng)格:支持 lambda 表達(dá)式和方法引用
- 延遲執(zhí)行:許多操作(中間操作)不會(huì)立即執(zhí)行,只有遇到終止操作才會(huì)執(zhí)行
- 可消費(fèi)性:Stream 只能被消費(fèi)一次,用完即失效
2. 操作類型
- 中間操作(Intermediate Operations):返回 Stream 本身,可以鏈?zhǔn)秸{(diào)用(如 filter, map)
- 終止操作(Terminal Operations):產(chǎn)生最終結(jié)果或副作用(如 forEach, collect)
二、創(chuàng)建 Stream 的多種方式
// 1. 從集合創(chuàng)建 List<String> list = Arrays.asList("a", "b", "c"); Stream<String> stream1 = list.stream(); // 順序流 Stream<String> parallelStream = list.parallelStream(); // 并行流 // 2. 從數(shù)組創(chuàng)建 String[] array = {"a", "b", "c"}; Stream<String> stream2 = Arrays.stream(array); // 3. 使用Stream.of() Stream<String> stream3 = Stream.of("a", "b", "c"); // 4. 使用Stream.generate() 無(wú)限流 Stream<Double> randomStream = Stream.generate(Math::random).limit(5); // 5. 使用Stream.iterate() 迭代流 Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2).limit(10);
三、常用的中間操作
1. 過(guò)濾操作
// filter(Predicate) 過(guò)濾符合條件的元素 List<String> filtered = list.stream() .filter(s -> s.startsWith("a")) .collect(Collectors.toList());
2. 映射操作
// map(Function) 將元素轉(zhuǎn)換為其他形式 List<Integer> lengths = list.stream() .map(String::length) .collect(Collectors.toList()); // flatMap 將多個(gè)流合并為一個(gè)流 List<String> flatMapped = list.stream() .flatMap(s -> Stream.of(s.split(""))) .collect(Collectors.toList());
3. 去重和排序
// distinct() 去重 List<String> distinct = list.stream().distinct().collect(Collectors.toList()); // sorted() 自然排序 List<String> sorted = list.stream().sorted().collect(Collectors.toList()); // sorted(Comparator) 自定義排序 List<String> customSorted = list.stream() .sorted((s1, s2) -> s2.compareTo(s1)) .collect(Collectors.toList());
4. 其他中間操作
// limit(long) 限制元素?cái)?shù)量 // skip(long) 跳過(guò)前N個(gè)元素 // peek(Consumer) 查看流中元素(主要用于調(diào)試)
四、常用的終止操作
1. 遍歷操作
// forEach(Consumer) 遍歷每個(gè)元素 list.stream().forEach(System.out::println);
2. 收集結(jié)果
// collect(Collector) 將流轉(zhuǎn)換為集合或其他形式 List<String> collectedList = stream.collect(Collectors.toList()); Set<String> collectedSet = stream.collect(Collectors.toSet()); Map<String, Integer> map = stream.collect( Collectors.toMap(Function.identity(), String::length));
3. 聚合操作
// count() 計(jì)數(shù) long count = list.stream().count(); // max/min(Comparator) 最大/最小值 Optional<String> max = list.stream().max(Comparator.naturalOrder()); // reduce 歸約操作 Optional<Integer> sum = Stream.of(1, 2, 3).reduce(Integer::sum);
4. 匹配操作
// anyMatch 任意元素匹配 boolean anyStartsWithA = list.stream().anyMatch(s -> s.startsWith("a")); // allMatch 所有元素匹配 boolean allStartsWithA = list.stream().allMatch(s -> s.startsWith("a")); // noneMatch 沒(méi)有元素匹配 boolean noneStartsWithZ = list.stream().noneMatch(s -> s.startsWith("z"));
五、數(shù)值流特化
Java 8 提供了專門的數(shù)值流,避免裝箱拆箱開(kāi)銷:
// IntStream, LongStream, DoubleStream IntStream intStream = IntStream.range(1, 100); // 1-99 DoubleStream doubleStream = DoubleStream.of(1.1, 2.2); // 常用數(shù)值操作 int sum = IntStream.rangeClosed(1, 100).sum(); // 1-100的和 OptionalDouble avg = IntStream.of(1, 2, 3).average();
六、并行流處理
// 創(chuàng)建并行流 List<String> parallelProcessed = list.parallelStream() .filter(s -> s.length() > 1) .collect(Collectors.toList()); // 注意事項(xiàng): // 1. 確保操作是線程安全的 // 2. 避免有狀態(tài)的操作 // 3. 數(shù)據(jù)量足夠大時(shí)才使用并行流
七、收集器(Collectors)的高級(jí)用法
// 分組 Map<Integer, List<String>> groupByLength = list.stream() .collect(Collectors.groupingBy(String::length)); // 分區(qū) Map<Boolean, List<String>> partition = list.stream() .collect(Collectors.partitioningBy(s -> s.startsWith("a"))); // 連接字符串 String joined = list.stream().collect(Collectors.joining(", ")); // 匯總統(tǒng)計(jì) IntSummaryStatistics stats = list.stream() .collect(Collectors.summarizingInt(String::length));
八、實(shí)際應(yīng)用示例
示例1:處理對(duì)象集合
List<Person> people = ...; // 獲取所有成年人的姓名列表 List<String> adultNames = people.stream() .filter(p -> p.getAge() >= 18) .map(Person::getName) .collect(Collectors.toList()); // 按城市分組 Map<String, List<Person>> byCity = people.stream() .collect(Collectors.groupingBy(Person::getCity)); // 計(jì)算每個(gè)城市的平均年齡 Map<String, Double> avgAgeByCity = people.stream() .collect(Collectors.groupingBy( Person::getCity, Collectors.averagingInt(Person::getAge) ));
示例2:文件處理
// 讀取文件并處理 try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) { long wordCount = lines .flatMap(line -> Arrays.stream(line.split("\\s+"))) .filter(word -> word.length() > 0) .count(); } catch (IOException e) { e.printStackTrace(); }
九、注意事項(xiàng)
- 流只能消費(fèi)一次:嘗試第二次使用已關(guān)閉的流會(huì)拋出
IllegalStateException
- 避免修改源數(shù)據(jù):流操作期間不應(yīng)修改源集合
- 合理使用并行流:并非所有情況都適合并行,小數(shù)據(jù)量可能適得其反
- 注意自動(dòng)裝箱:數(shù)值操作盡量使用原始類型特化流(IntStream等)
- 延遲執(zhí)行特性:沒(méi)有終止操作,中間操作不會(huì)執(zhí)行
Stream API 提供了一種高效、聲明式的數(shù)據(jù)處理方式,是現(xiàn)代 Java 編程中不可或缺的工具。合理使用可以大幅提升代碼的可讀性和維護(hù)性。
到此這篇關(guān)于java的Stream流處理的文章就介紹到這了,更多相關(guān)java Stream流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Java中避免NullPointerException的解決方案
這篇文章主要介紹了在Java中避免NullPointerException的解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04volatile可見(jiàn)性的一些認(rèn)識(shí)和論證
volatile的關(guān)鍵詞的使用在JVM內(nèi)存模型中已是老生常談了,這篇文章主要結(jié)合自己對(duì)可見(jiàn)性的一些認(rèn)識(shí)和一些直觀的例子來(lái)談?wù)剉olatile,感興趣的朋友一起看看吧2017-08-08java?spring?validation?自動(dòng)、手動(dòng)校驗(yàn)
HibernateValidator簡(jiǎn)化了Java開(kāi)發(fā)中的參數(shù)校驗(yàn)過(guò)程,提供自動(dòng)和手動(dòng)兩種校驗(yàn)方式,通過(guò)引入相關(guān)依賴并使用@Validated注解,可以實(shí)現(xiàn)自動(dòng)校驗(yàn),手動(dòng)校驗(yàn)則需要使用ValidatorUtils類,此方法有效減少代碼重復(fù),提高開(kāi)發(fā)效率2024-09-09Java BeanUtils.copyProperties的詳解
這篇文章主要介紹了Java BeanUtils.copyProperties的詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08深入學(xué)習(xí)java內(nèi)存化和函數(shù)式協(xié)同
這篇文章主要介紹了深入學(xué)習(xí)java內(nèi)存化和函數(shù)式協(xié)同,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06java同步器AQS架構(gòu)AbstractQueuedSynchronizer原理解析
這篇文章主要為大家介紹了java同步器AQS架構(gòu)AbstractQueuedSynchronizer的底層原理及源碼解析,有需要的朋友可以借鑒參考下,希望能有所幫助,祝大家多多進(jìn)步早日升職加薪2022-03-03java實(shí)現(xiàn)基于SMTP發(fā)送郵件的方法
這篇文章主要介紹了java實(shí)現(xiàn)基于SMTP發(fā)送郵件的方法,實(shí)例分析了java基于SMTP服務(wù)發(fā)送郵件的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07Java使用LinkedHashMap進(jìn)行分?jǐn)?shù)排序
這篇文章主要介紹了Java使用LinkedHashMap進(jìn)行分?jǐn)?shù)排序的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05mybatis-plus指定字段模糊查詢的實(shí)現(xiàn)方法
最近項(xiàng)目中使用springboot+mybatis-plus來(lái)實(shí)現(xiàn),所以下面這篇文章主要給大家介紹了關(guān)于mybatis-plus實(shí)現(xiàn)指定字段模糊查詢的相關(guān)資料,需要的朋友可以參考下2022-04-04