使用 java 流应用程序接口
最编程
2024-10-10 07:03:46
...
Java Stream API 是 Java 8 引入的一个重要特性,它提供了一种高效且易于使用的处理集合的方式。Stream API 支持函数式编程风格,可以对集合进行复杂的转换和操作,如过滤、映射、排序、聚合等。
Stream API 的基本概念
Stream API 主要有三个核心组件:
-
源(Source):数据流的来源,通常是集合(如
List
、Set
等)或其他数据结构。 -
中间操作(Intermediate Operations):一系列可以按顺序链接在一起的数据处理操作,如
filter
、map
、sorted
等。 -
终止操作(Terminal Operations):结束流的操作,产生最终结果或副作用,如
collect
、forEach
、findFirst
等。
Stream API 的基本使用
创建 Stream
创建 Stream 的常见方式有:
-
从集合创建 Stream:
- 使用集合的
stream()
或parallelStream()
方法创建 Stream。
- 使用集合的
-
从数组创建 Stream:
- 使用
Arrays.stream(array)
方法创建 Stream。
- 使用
-
从迭代器创建 Stream:
- 使用
Stream.iterate(seed, next)
方法创建无限流。
- 使用
-
从生成器创建 Stream:
- 使用
Stream.generate(generator)
方法创建无限流。
- 使用
中间操作(Intermediate Operations)
中间操作可以链接在一起,形成流水线式的处理过程。常见的中间操作包括:
-
filter(Predicate<T> predicate)
:筛选元素。 -
map(Function<T, R> mapper)
:转换元素。 -
flatMap(Function<T, Stream<R>> mapper)
:将嵌套的 Stream 展平。 -
distinct()
:去重。 -
sorted()
:排序。 -
peek(Consumer<T> action)
:打印或调试输出。
终止操作(Terminal Operations)
终止操作结束 Stream,产生最终结果或副作用。常见的终止操作包括:
-
forEach(Consumer<T> action)
:遍历流中的每个元素。 -
collect(Collector<T, A, R> collector)
:收集流中的元素。 -
reduce(BinaryOperator<T>)
:聚合流中的元素。 -
anyMatch(Predicate<T> predicate)
:判断是否有元素满足条件。 -
allMatch(Predicate<T> predicate)
:判断所有元素是否满足条件。 -
noneMatch(Predicate<T> predicate)
:判断是否有元素不满足条件。 -
findFirst()
:获取第一个元素。 -
findAny()
:获取任意一个元素。 -
count()
:计算元素数量。 -
max(Comparator<T> comparator)
:获取最大元素。 -
min(Comparator<T> comparator)
:获取最小元素。
示例代码
示例 1:基本使用
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 过滤偶数
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers); // 输出 [2, 4, 6, 8, 10]
// 映射平方
List<Integer> squares = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println(squares); // 输出 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
// 排序
List<Integer> sortedNumbers = numbers.stream()
.sorted((a, b) -> b - a)
.collect(Collectors.toList());
System.out.println(sortedNumbers); // 输出 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
// 去重
List<Integer> uniqueNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(uniqueNumbers); // 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (原列表已经是唯一的)
// 遍历输出
numbers.stream()
.forEach(System.out::println);
// 打印每个元素
numbers.stream()
.peek(System.out::println)
.collect(Collectors.toList());
}
}
示例 2:复杂操作
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ComplexStreamExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
// 过滤长度大于 5 的名字,并转换成大写
List<String> longNamesUpper = names.stream()
.filter(name -> name.length() > 5)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(longNamesUpper); // 输出 [CHARLIE, DAVID]
// 计算名字长度的总和
int totalLength = names.stream()
.mapToInt(String::length)
.sum();
System.out.println(totalLength); // 输出 23
// 检查是否有名字长度大于 5
boolean hasLongName = names.stream()
.anyMatch(name -> name.length() > 5);
System.out.println(hasLongName); // 输出 true
// 获取最长的名字
String longestName = names.stream()
.max(Comparator.comparingInt(String::length))
.orElse(null);
System.out.println(longestName); // 输出 Charlie
// 获取最短的名字
String shortestName = names.stream()
.min(Comparator.comparingInt(String::length))
.orElse(null);
System.out.println(shortestName); // 输出 Bob
// 分组统计每个名字的长度出现次数
Map<Integer, Long> lengthCount = names.stream()
.collect(Collectors.groupingBy(String::length, Collectors.counting()));
System.out.println(lengthCount); // 输出 {3=2, 5=1, 6=1, 7=1}
// 归约操作
int product = names.stream()
.mapToInt(name -> name.length())
.reduce(1, (a, b) -> a * b);
System.out.println(product); // 输出 34560
}
}
Stream API 的高级用法
1. 并行流(Parallel Streams)
并行流可以提高处理大量数据时的效率。
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
public class ParallelStreamExample {
public static void main(String[] args) {
Random random = new Random();
List<Integer> numbers = IntStream.rangeClosed(1, 1000000)
.boxed()
.collect(Collectors.toList());
// 使用并行流计算总和
long parallelSum = numbers.parallelStream()
.reduce(0L, Long::sum);
System.out.println(parallelSum); // 输出 500000500000
}
}
2. 构建复杂的数据结构
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ComplexDataStructureExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
// 构建一个 Map,键是名字长度,值是对应的名字列表
Map<Integer, List<String>> lengthToNames = names.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(lengthToNames); // 输出 {3=[Bob, Eve], 5=[Alice], 7=[Charlie], 6=[David]}
}
}
总结
Java Stream API 提供了一种高效且易于使用的处理集合的方式。通过使用 Stream API,可以轻松实现复杂的集合操作,如过滤、映射、排序、聚合等。掌握 Stream API 的基本概念和用法后,可以更好地利用这些特性来编写高效、简洁的 Java 应用程序。
通过上述示例代码,可以看到 Stream API 如何简化集合操作,并提供更多的功能和灵活性。无论是简单的筛选和映射,还是复杂的聚合和分组,Stream API 都能够胜任。
上一篇: make的使用
推荐阅读
-
使用 java 流应用程序接口
-
Java 8新特性探究(十三)JavaFX 8新特性以及开发2048游戏-JavaFX历史## 跟java在服务器端和web端成绩相比,桌面一直是java的软肋,于是Sun公司在2008年推出JavaFX,弥补桌面软件的缺陷,请看下图JavaFX一路走过来的改进 从上图看出,一开始推出时候,开发者需使用一种名为JavaFX Script的静态的、声明式的编程语言来开发JavaFX应用程序。因为JavaFX Script将会被编译为Java bytecode,程序员可以使用Java代码代替。 JavaFX 2.0之后的版本摒弃了JavaFX Script语言,而作为一个Java API来使用。因此使用JavaFX平台实现的应用程序将直接通过标准Java代码来实现。 JavaFX 2.0 包含非常丰富的 UI 控件、图形和多媒体特性用于简化可视化应用的开发,WebView可直接在应用中嵌入网页;另外 2.0 版本允许使用 FXML 进行 UI 定义,这是一个脚本化基于 XML 的标识语言。 从JDK 7u6开始,JavaFx就与JDK捆绑在一起了,JavaFX团队称,下一个版本将是8.0,目前所有的工作都已经围绕8.0库进行。这是因为JavaFX将捆绑在Java 8中,因此该团队决定跳过几个版本号,迎头赶上Java 8。 ##JavaFx8的新特性 ## ###全新现代主题:Modena 新的Modena主题来替换原来的Caspian主题。不过在Application的start方法中,可以通过setUserAgentStylesheet(STYLESHEET_CASPIAN)来继续使用Caspian主题。 参考http://fxexperience.com/2013/03/modena-theme-update/ ###JavaFX 3D 在JavaFX8中提供了3D图像处理API,包括Shape3D (Box, Cylinder, MeshView, Sphere子类),SubScene, Material, PickResult, LightBase (AmbientLight 和PointLight子类),SceneAntialiasing等。Camera类也得到了更新。从JavaDoc中可以找到更多信息。 ###富文本 强化了富文本的支持 ###TreeTableView ###日期控件DatePicker 增加日期控件 ###用于 CSS 结构的公共 API
-
使用Java流对MP4视频文件进行加密,并在H5中播放加密的视频流
-
实现实时推流直播:使用Java连接大华摄像头获取视频流
-
如何使用Java开发手机应用程序
-
深入理解Java工作流:六大流行工作流框架详解 - 何为工作流(Workflow)及其实践应用
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
如何在Eclipse中使用Java JPDA进行远程应用程序调试 - 配置Java应用的步骤指南
-
在Linux环境中使用JPDA和Tomcat进行Java应用的远程调试指南
-
使用SQLE进行Java应用的自动SQL审核指南