赞
踩
Java 8 中有两个重要的改变,一个是 Lambda 表达式,另外一个是 Stream API(java.util.stream.*)
Stream 流的特点:
// 支持顺序和并行聚合操作的元素序列
A sequence of elements supporting sequential and parallel aggregate operations.
// 以下示例演示了使用Stream和IntStream的聚合操作:
The following example illustrates an aggregate operation using Stream and IntStream:
// 示例:
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定希望对集合进行的操作,可以执行复杂的查找、过滤和映射数据等操作
最上面的 AutoCloseable
这个接口只有一个方法
void close() throws Exception;
这个方法关闭调用对象,释放可能占用的所有资源。在带资源的try语句的末尾,会自动调用该方法,不用显式调用close()方法
BaseStream
这个接口是 Stream 流的基类,这个类定义了 Stream 流的主要行为
public interface BaseStream<T, S extends BaseStream<T, S>> extends AutoCloseable {
//获得流的迭代器(终端操作)
Iterator<T> iterator();
// 获取流的并行迭代器(终端操作)
Spliterator<T> spliterator();
// 并行流返回true,顺序流返回false
boolean isParallel();
// 返回一个顺序流(中间操作)
S sequential();
// 返回一个并行流(中间操作)
S parallel();
// 返回一个无序流(中间操作)
S unordered();
// 关闭流时调用,返回一个新流
S onClose(Runnable closeHandler);
// 父类 AutoCloseable 关闭流的方法
@Override
void close();
}
Stream 流上的操作可以分为 中间操作(Intermediate)和终端操作(Terminal)
中间操作
终端操作
通过 Collection
接口的 stream()
或者 parallelStream()
方法创建
List<String> list = Arrays.asList("1", "2", "3");
// 创建普通流,主线程按顺序对流进行操作
Stream<String> stream1 = list.stream();
// 创建并行流,多线程并行对流进行操作
Stream<String> stream2 = list.parallelStream();
// 使用 parallel() 将顺序流转换为并行流
Stream<String> stream8 = stream1.parallel();
使用 Stream
的静态方法
Stream<String> stream3 = Stream.empty();
Stream<String> stream4 = Stream.of("1", "2", "3");
// 将两个流连接起来
Stream<String> stream5 = Stream.concat(stream1, stream2);
... ...
Stream.generate();
Stream.iterate();
使用 Arrays
的 stream()
方法
int[] arr = {1, 2, 3};
IntStream stream = Arrays.stream(arr);
filter(Predicate):筛选
,结果为 false 的元素会过滤掉
List<String> list = Arrays.asList("1", "2", "3", "4", "5");
// 筛选等于 "3" 的第一个元素
Optional<String> first = list.stream().filter(x -> x == "3").findFirst();
System.out.println(first.get()); // 输出结果:3
map:映射
map(fun):转换元素的值,一个流的元素按函数处理后映射为新的元素
List<String> list = Arrays.asList("he", "ha", "hia", "hua");
// 所有元素大写
list.stream().map(x -> x.toUpperCase()).forEach(System.out::println);
// 输出结果:HE HA HIA HUA
flatMap(fun):流中的每个值都换成另外一个流,再将所有的流连接成一个
List<String> list = Arrays.asList("h-e", "h-a", "h-i-a", "h-u-a");
List<String> collect = list.stream().flatMap(x -> Arrays.stream(x.split("-"))).collect(Collectors.toList());
System.out.println(collect);
// 输出结果:[h, e, h, a, h, i, a, h, u, a]
limit(n):截取
,保留 n 个元素
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6);
// 保留 3 个元素
list.stream().limit(3).forEach(System.out::println);
// 输出结果:1 2 3
skip(n):跳过
,跳过 n 个元素
List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3");
// 跳过 3 个元素筛选等于 "3" 的第一个元素
Optional<String> first = list.stream().skip(3).filter(x -> x == "3").findFirst();
System.out.println(first); // 输出结果:3
distinct():去重
,去除重复元素
List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3");
// 去重遍历
list.stream().distinct().forEach(System.out::println);
sorted:排序
自然排序
List<Integer> list = Arrays.asList(5, 2, 3, 4, 5, 2, 3, 6);
// 去重并排序
List<Integer> collect = list.stream().distinct().sorted().collect(Collectors.toList());
System.out.println(collect);
foreach:遍历
List<String> list = Arrays.asList("he", "ha", "hia", "hua");
// 遍历输出
list.stream().forEach(x -> {
System.out.println(x);
});
// 结果:he ha hia hua
find
List<String> list = Arrays.asList("1", "2", "3", "4", "5");
// 筛选等于 "3" 的第一个元素
Optional<String> first = list.stream().filter(x -> x == "3").findFirst();
System.out.println(first.get()); // 输出结果:3
count()
List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3");
// 等于 "3" 的元素的数量
long count = list.stream().filter(x -> x == "3").count();
System.out.println(count); // 输出结果:2
max(Comparator)
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6);
// 集合中最大的元素
Optional<Integer> max = list.stream().max(Integer::compareTo);
System.out.println(max.get()); // 结果为:6
min(Comparator)
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6);
// 集合中最小的元素
Optional<Integer> max = list.stream().min(Integer::compareTo);
System.out.println(max.get()); // 结果为:1
reduce:缩减,可以把一个 stream 流缩减成一个值,实现求和、求最值等操作
求和
// 对集合中的元素求和
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 第一种求和方式
Integer sum = list.stream().reduce((x, y) -> x + y).get();
// 第二种求和方式
Integer sum2 = list.stream().reduce(Integer::sum).get();
// 第三种求和方式(集合中的元素求和再加 1)
Integer sum3 = list.stream().reduce(3, Integer::sum);
求最值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 求最大值 1
Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
// 求最大值 2
Integer sum2 = list.stream().reduce(Integer::max).get();
collect:收集操作,把 stream 流收集起来,成为一个新的值或者集合
toList
、toSet
、toMap
List<String> list = Arrays.asList("he", "ha", "hia", "hua", null);
// toList
List<String> collect = list.stream().filter(Objects::nonNull).collect(Collectors.toList());
System.out.println(collect); //[he, ha, hia, hua]
// toSet
Set<String> set = list.stream().filter(Objects::nonNull).collect(Collectors.toSet());
System.out.println(set); // [hia, hua, ha, he]
// toMap
Map<String, String> map = list.stream().filter(Objects::nonNull).collect(Collectors.toMap(x -> x, x -> x));
System.out.println(map); // {hia=hia, hua=hua, ha=ha, he=he}
平均值 averagingDouble
、 averagingLong
、averagingInt
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 求平均值
Double average = list.stream().collect(Collectors.averagingDouble(Integer::intValue));
System.out.println(average);
计数 count
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 求总数
Long count = list.stream().collect(Collectors.counting());
System.out.println(count);
最值 maxBy
、minBy
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 求最高值
Integer max = list.stream().collect(Collectors.maxBy(Integer::compare)).get();
System.out.println(max);
求和 summingInt
、summingLong
、summingDubbo
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 求和
Integer sum = list.stream().collect(Collectors.summingInt(Integer::intValue));
System.out.println(sum);
统计所有 summarizingInt
、summarizingLong
、summarizingDouble
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 统计所有信息
DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(Integer::intValue));
System.out.println(collect);
分组 partitioningBy(按条件分区)
、groupingBy(可按条件多次分组)
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 23, 6, -19, 32, 5, 12, 8);
// 按照是否大于 10 进行分组
Map<Boolean, List<Integer>> collect = list.stream().collect(Collectors.partitioningBy(x -> x > 10));
System.out.println(collect);
// 返回结果:{false=[1, 2, 3, 4, 5, 6, 6, -19, 5, 8], true=[23, 32, 12]}
// 按照是否大于 10 进行分组后,再按照是否大于 15 进行分组
Map<Object, Map<Object, List<Integer>>> collect2 = list.stream().collect(Collectors.groupingBy(x -> x > 10, Collectors.groupingBy(x -> x > 15)));
System.out.println(collect2);
// 返回结果:{false={false=[1, 2, 3, 4, 5, 6, 6, -19, 5, 8]}, true={false=[12], true=[23, 32]}}
连接 joining
流中的元素用一个连接符进行拼接
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 23, 6, -19, 32, 5, 12, 8);
// 去重并用 ~ 拼接
String collect = list.stream().distinct().map(x -> x.toString()).collect(Collectors.joining("~"));
排序 sorted(Comparator)
:自定义排序
List<Integer> list = Arrays.asList(5, 2, 3, 4, 5, 2, 3, 6);
// 去重并排序
List<Integer> collect = list.stream().distinct().sorted().collect(Collectors.toList());
System.out.println(collect);
// 输出结果:[-19, 1, 2, 3, 4, 5, 6, 8, 12, 23, 32]
合并 Stream.concat(stream1, stream2)
List<Integer> list1 = Arrays.asList(5, 2, 3, 4, 5, 2, 3, 6);
List<Integer> list2 = Arrays.asList(1, 6, 23, -19, 32, 5, 12, 8);
// 去重合并两个流输出
Stream.concat(list1.stream(), list2.stream()).distinct().sorted(Integer::compareTo).forEach(System.out::print);
// 输出结果:-19 1 2 3 4 5 6 8 12 23 32
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。