流操作
Java 8 的 Stream 流操作是 Java 8 对集合操作功能的增强,方便对集合筛选、 排序、聚合等。借助 Lambda 表达式,提高编程效率和可读性。Stream并不会去存储元素,而是负责相关计算,使用起来更像一个高级的迭代器。由于 Stream 流提供了惰性计算和并行处理的能力,在使用并行计算方式时数据会被自动分解成多段然后并行处理,最后将结果汇总。所以 Stream 操作可以让程序运行变得更加高效。
生成流
在 Java 8 中, 集合接口有两个方法来生成流:
stream()
− 为集合创建串行流。parallelStream()
− 为集合创建并行流。
List<String> strings = Arrays.asList("a", "", "b", "c", "d","", "e");
// stream,过滤流中的空串
List<String> collect = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println(collect);
//并行处理,统计空串数量
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
System.out.println("统计空串数量:"+count);
运行结果:
forEach
forEach
方法用来迭代流中的每个数据
Random random = new Random();
random.ints().limit(3).forEach(System.out::println);
运行结果:
filter
filter
方法用于通过设置的条件过滤出元素。
List<String> stringList = Arrays.asList("a","b","c","d","e","","a");
// 过滤空串
List<String> filtered = stringList.stream().filter(e -> !e.isEmpty()).collect(Collectors.toList());
filtered.forEach(System.out:: println);
运行结果:
limit/ skip
获取或者去掉前 n 个元素
Random random = new Random();
// 获取前10位随机产生0-10(不包括)之间的IntStream,打印出来
random.ints(0,10).limit(10).forEach(System.out::println);
运行结果:
map/flatMap
map
方法用于映射每个元素到对应的结果,把数据进行一对一的映射;一对多可以使用 flatMap。
List<Integer> numbers = Arrays.asList(1, 2, 5, 6, 6, 6, 8);
// 获取元素对应的平方数并去重
List<Integer> integerList = numbers.stream().map(e -> e * e).distinct().collect(Collectors.toList());
integerList.forEach(System.out::println);
运行结果:
Stream<List<Integer>> listStream = Stream.of(Arrays.asList(1,3,5), Arrays.asList(2,4,6), Arrays.asList(5, 6));
List<Integer> collect = listStream.flatMap((childList) -> childList.stream()).collect(Collectors.toList());
collect.forEach(number -> System.out.print(number + ","));
运行结果:
count
List<String> strings = Arrays.asList("a", "", "b", "c", "d","", "e");
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
System.out.println("统计空串数量:"+count);
运行结果:
sorted
sorted
方法用于对流进行排序。
List<Integer> integers = Arrays.asList(1,8,1,2,2,7,2,5,88,9);
List<Integer> collect = integers.stream().distinct().sorted().collect(Collectors.toList());
collect.forEach(System.out::println);
运行结果:
findFirst
findFirst
可以查找出 Stream 流中的第一个元素,它返回的是一个 Optional 类型。
List<Integer> integerList =Arrays.asList(1,8,1,2,2,7,2,5,88,9);
Optional<Integer> first = integerList.stream().findFirst();
System.out.println(first.orElse(9999));
运行结果:
collect / toArray
Stream 流可以轻松的转换为其他结构。
List<Integer> numberList = Arrays.asList(1,2,2,6,6,5,3,9);
Integer[] toArray = numberList.stream().toArray(Integer[]::new);
System.out.println("转换成整型数组:"+ JSON.toJSONString(toArray));
List<Integer> integerList = numberList.stream().distinct().collect(Collectors.toList());
System.out.println("去重后转换成list:"+integerList);
Set<Integer> integerSet = numberList.stream().collect(Collectors.toSet());
System.out.println("转换成Set:"+ integerSet);
String toString = numberList.stream().map(number -> String.valueOf(number)).collect(Collectors.joining()).toString();
System.out.println("将每个元素映射成String并拼接成字符串:"+toString);
String toString1 = numberList.stream().map(number -> String.valueOf(number)).collect(Collectors.joining(",")).toString();
System.out.println("将每个元素映射成String并以“,”隔断拼接成字符串:"+toString1);
运行结果:
Statistics
数学统计功能,获取数组的最大值、最小值、个数、和、平均数等
List<Integer> numberList = Arrays.asList(1,1,1,2,2,3,3,4);
IntSummaryStatistics intSummaryStatistics = numberList.stream().mapToInt(e -> e).summaryStatistics();
System.out.println("平均数:"+intSummaryStatistics.getAverage());
System.out.println("最大数:"+intSummaryStatistics.getMax());
System.out.println("和:" + intSummaryStatistics.getSum());
运行结果:
groupingBy
分组聚合,和数据库的 Group by 的功能相同。
List<Integer> ageList = Arrays.asList(11, 22, 13, 14, 25, 26, 35, 40, 49);
Map<String, List<Integer>> ageGroupMap = ageList.stream().collect(Collectors.groupingBy( age -> String.valueOf(age / 10)));
System.out.println("ageGroupMap:" + GsonUtil.toJson(ageGroupMap));
ageGroupMap.forEach((age, list) -> System.out.println("年龄" + age + "0多岁的有:" + list));
运行结果:
partitioningBy
按某个条件分组
List<Integer> integerList = Arrays.asList(17,22,16,15,25,26,18);
Map<Boolean, List<Integer>> booleanListMap = integerList.stream().collect(Collectors.partitioningBy(age -> age%2==0));
System.out.println("booleanListMap:" + booleanListMap);
System.out.println("奇数:" + booleanListMap.get(false));
System.out.println("偶数:" + booleanListMap.get(true));
运行结果: