原创作者,公众号【IT技术馆】,欢迎关注公众号,转载文章请注明出处哦。
别死脑筋,赶紧学起来!Java之Steam() API 常用方法使用,让开发简单起来!
Java 的 Stream API 是 Java 8 引入的一个关键特性,提供了一种声明性的方式来处理数据集合(如集合、数组等)。通过 Stream API,你可以以简洁、高效的方式执行复杂的查询、过滤、转换和聚合操作。以下是对 Stream API 的详细解释和一些示例。
Java Stream API支持的功能
功能 | 描述 |
---|---|
filter |
过滤流中的元素,根据条件只留下满足条件的元素 |
map |
将流中的每个元素映射成其他形式,结果是一个包含映射后结果的新流 |
sorted |
确保流中的元素在消费时的顺序按照自然顺序或自定义Comparator排序 |
collect |
将流转换为其他形式,如List、Set或Map,或者是自定义的收集器 |
forEach |
遍历流中的每个元素并执行给定的操作 |
reduce |
通过重复处理其元素来将流减少到单个汇总结果 |
anyMatch |
检查流中的元素是否有一个满足给定的条件 |
allMatch |
检查流中的元素是否全部满足给定条件 |
noneMatch |
检查流中的元素是否没有满足给定条件的 |
findFirst |
返回流中的第一个元素,如果流为空,则返回空的Optional |
limit |
截断流,使其最大长度不超过给定数量 |
skip |
跳过流中的前n个元素,返回包含余下元素的新流 |
使用Java Stream API的优势
功能 | Java Stream API | 传统集合操作 |
---|---|---|
数据处理模式 | 声明式,支持函数式编程 | 命令式,代码较为复杂 |
内存效率 | 更高,因为它是在流上直接操作 | 低,需要复制到新的数据结构 |
并发处理 | 内建支持并发处理 | 手动处理并发 |
可读性 | 高,流操作可链式调用 | 低,循环和条件判断多 |
使用场景 | 数据集合操作,大数据处理 | 小数据量操作 |
常用的 Java Stream API功能
Java中的Stream API是Java 8引入的一个关键抽象概念,它允许你以声明性方式处理数据集合(如数组、列表等)。Stream API提供了一套丰富的操作来过滤、转换、聚合数据等。以下是Stream API中一些常用的API介绍及示例:
1. 创建Stream
- 从集合创建:可以使用
Collection
接口中的stream()
方法。
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
- 从数组创建:可以使用
Arrays.stream(T[] array)
方法。
int[] array = {
1, 2, 3};
Stream<Integer> stream = Arrays.stream(array);
- 创建空Stream:可以使用
Stream.empty()
方法。
Stream<String> emptyStream = Stream.empty();
- 使用Stream.of:可以从一组值中创建Stream。
Stream<String> streamOfValues = Stream.of("a", "b", "c");
- 使用Stream.builder:可以使用
Stream.Builder
来构建Stream。
Stream.Builder<String> builder = Stream.builder();
builder.add("a");
builder.add("b");
Stream<String> streamFromBuilder = builder.build();
2. 中间操作
中间操作返回一个新的Stream,并且它们是惰性求值的,只有在调用终端操作时才会执行。
- filter:过滤元素。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
// 输出: ["Alice"]
- map:将每个元素映射为另一个类型。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
// 输出: [5, 3, 7]
- sorted:对流中的元素进行排序。
List<String> names = Arrays.asList("Bob", "Alice", "Charlie");
List<String> sortedNames = names.stream()
.sorted()
.collect(Collectors.toList());
// 输出: ["Alice", "Bob", "Charlie"]
- distinct:去除流中的重复元素。
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
// 输出: [1, 2, 3, 4]
- limit:截取流中的前n个元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> limitedNumbers = numbers.stream()
.limit(3)
.collect(Collectors.toList());
// 输出: [1, 2, 3]
- skip:跳过前n个元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skippedNumbers = numbers.stream()
.skip(2)
.collect(Collectors.toList());
// 输出: [3, 4, 5]
3. 终端操作
终端操作产生结果或者副作用,并且执行后会结束流。
- forEach:对流中的每个元素执行某种操作。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
// 输出: Alice, Bob, Charlie
- collect:将流中的元素收集到某种结果中。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> collectedNames = names.stream()
.collect(Collectors.toList());
// 输出: ["Alice", "Bob", "Charlie"]
- reduce:对流中的元素进行累积操作。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
int sum = numbers.stream()
.reduce(0, Integer::sum);
// 输出: 10
- count:返回流中元素的个数。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream().count();
// 输出: 3
- findFirst:返回流中的第一个元素(作为Optional对象)。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Optional<String> firstName = names.stream()
.findFirst();
// 输出: Optional["Alice"]
- anyMatch:检查流中是否有任意元素匹配给定的条件。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
boolean hasAlice = names.stream()
.anyMatch(name -> name.equals("Alice"));
// 输出: true
4. 其他高级操作
- flatMap:将流中的每个元素映射为另一个流,并将结果合并为一个流。
List<String> names = Arrays.asList("Alice", null, "Bob", null, "Charlie");
List<String> nonNullNames = names.stream()
.flatMap(Stream::ofNullable)
.collect(Collectors.toList());
// 输出: ["Alice", "Bob", "Charlie"]
- iterate:创建无限的序列流。
Stream.iterate(0, n -> n + 2)
.limit(10)
.forEach(System.out::println);
// 输出: 0, 2, 4, 6, 8, 10, 12, 14, 16, 18
- collectingAndThen:对收集器的结果执行特殊类型的转换。
List<String> fruits = Arrays.asList("apple", "banana", "orange");
Map<Integer, String> result = fruits.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(fruits::indexOf, String::toUpperCase),
Collections::unmodifiableMap
));
// 输出: {0="APPLE", 1="BANANA", 2="ORANGE"}
- dropWhile 和 takeWhile(Java 9+):连续处理流。
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
numbers.stream()
.dropWhile(n -> n < 3)
.takeWhile(n -> n < 6)
.forEach(System.out::println);
// 输出: 3, 4, 5
- IntStream:用于快速生成整数流。
IntStream.range(1, 5).forEach(System.out::println);
// 输出: 1, 2, 3, 4
IntStream.rangeClosed(1, 5).forEach(System.out::println);
// 输出: 1, 2, 3, 4, 5
- teeing(Java 12+):在元素流上一起应用两个单独的收集器。
Stream<Integer> nums = Stream.of(1, 2, 3, 4, 5);
Map<String, Integer> collect = nums.collect(Collectors.teeing(
Collectors.maxBy(Integer::compareTo),
Collectors.minBy(Integer::compareTo),
(e1, e2) -> Map.of("min", e1.get(), "max", e2.get())
));
// 输出: {max=5, min=1}
- concat:连接两个流并生成一个新流。
Stream<Integer> stream1 = Stream.of(1, 2, 3);
Stream<Integer> stream2 = Stream.of(4, 5, 6);
Stream.concat(stream1, stream2).forEach(System.out::println);
// 输出: 1, 2, 3, 4, 5, 6
- partitioningBy:对流进行分组。
Stream<String> fruits = Stream.of("apple", "banana", "orange", "grape");
Map<Boolean, List<String>> result = fruits.collect(Collectors.partitioningBy(f -> f.length() > 5));
// 输出