JAVA8 stream 集合处理
所属分类 java8
浏览量 2749
Stream lambda
Stream 流
将集合转换为 流 ,元素序列
通过声明方式,对集合中的每个元素进行一系列并行或串行的流水线操作。
数据源 流 中间操作 终端操作
List 集合转换为 Stream 类型的流
过滤 排序 类型转换
终端操作,可以把 Stream 转换回集合类型 或者 打印 计数 求和 求平均 计算最大值最小值 等
List newList = list.stream().map(Person::getName).sorted().limit(10).collect(Collectors.toList());
List list = Arrays.asList("x","a","d","c");
Stream stream = list.stream().sorted().limit(3);
List newList1 = stream.collect(Collectors.toList());
// java.lang.IllegalStateException: stream has already been operated upon or closed
// List newList2 = stream.collect(Collectors.toList());
流只能迭代一次
stream()
parallelStream()
filter(T -> boolean)
保留 boolean 为 true 的元素
保留年龄为 20 的 person
list = list.stream().filter(person -> person.getAge() == 20).collect(toList());
distinct() 去除重复元素
通过 equals 方法 判断两个元素是否相等
sorted()
sorted((T, T) -> int)
如果流中的元素实现了 Comparable 接口,可以直接调用 sorted() 排序
根据年龄大小来比较:
list = list.stream().sorted((p1, p2) -> p1.getAge() - p2.getAge()).collect(toList());
list = list.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(toList());
limit(long n) 返回前 n 个元素
skip(long n) 跳 前 n 个元素
map(T -> R)
将流中的每一个元素 T 映射为 R(类似类型转换)
List newlist = list.stream().map(Person::getName).collect(toList());
flatMap(T -> Stream)
将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流
List list = new ArrayList<>();
list.add("are you ok");
list.add("i am fine");
list = list.stream().map(s -> s.split(" ")).flatMap(Arrays::stream).collect(toList());
anyMatch(T -> boolean)
boolean b = list.stream().anyMatch(person -> person.getAge() == 20);
allMatch(T -> boolean)
noneMatch(T -> boolean)
Optional findAny()
Optional findFirst()
reduce((T, T) -> T) 和 reduce(T, (T, T) -> T)
用于组合流中的元素,如求和,求积,求最大值等
求和
计算年龄总和:
int sum = list.stream().map(Person::getAge).reduce(0, (a, b) -> a + b);
int sum = list.stream().map(Person::getAge).reduce(0, Integer::sum);
第一个参数为初始值
可以不提供初始值 ,返回 Optional
Optional sum = list.stream().map(Person::getAge).reduce(Integer::sum);
long count()
collect()
collect(toList()) collect(toSet())
forEach
list.stream().forEach(System.out::println);
数值流
IntStream, DoubleStream, LongStream
使用原始类型 int,double,long 避免 Box unbox
流转换为数值流
mapToInt(T -> int) : return IntStream
mapToDouble(T -> double) : return DoubleStream
mapToLong(T -> long) : return LongStream
IntStream intStream = list.stream().mapToInt(Person::getAge);
数值流转换为流
Stream stream = intStream.boxed();
数值流方法
sum()
max()
min()
average()
数值范围
range 和 rangeClosed
闭区间 半开半闭区间
1 到 10 求和
IntStream intStream = IntStream.rangeClosed(1, 10);
int sum = intStream.sum();
Optional 类 解决空指针问题
isPresent() 值存在时返回 true
get() 获取当前值,值不存抛异常
orElse(T) 值存在时返回该值,否则返回 T 值
创建流
Stream stream = Stream.of("hello", "Java8");
Stream.empty()
根据数组创建流
Arrays.stream(T[])
Arrays.stream(int[])
Arrays.stream(double[])
Arrays.stream(long[])
// 只取索引第 1 到第 2 位 , 切片 [1,3)
int[] a = {1, 2, 3, 4};
Arrays.stream(a, 1, 3).forEach(System.out::println);
文件生成流
Stream stream = Files.lines(Paths.get("data.txt"));
函数生成流
首元素为 0,之后依次加 2
Stream.iterate(0, n -> n + 2)
Stream.generate(Math :: random)
元素全为 1
Stream.generate(() -> 1)
collect 收集数据
toList
toSet
toCollection
toMap
List newlist = list.stream.collect(toList());
// Map Key 重复,报错
Map map = list.stream().collect(toMap(Person::getAge, p -> p));
汇总
long count = list.stream().collect(counting());
long count = list.stream().count();
summingInt ,summingLong ,summingDouble
int sum = list.stream().collect(summingInt(Person::getAge));
int sum = list.stream().mapToInt(Person::getAge).sum();
int sum = list.stream().map(Person::getAge).reduce(Interger::sum).get();
函数式编程通常提供多种方式来完成同一种操作
averagingInt,averagingLong,averagingDouble
Double average = list.stream().collect(averagingInt(Person::getAge));
OptionalDouble average = list.stream().mapToInt(Person::getAge).average();
注意返回类型不同!!!
summarizingInt,summarizingLong,summarizingDouble
IntSummaryStatistics stat = list.stream().collect(summarizingInt(Person::getAge));
取最值
Optional optional = list.stream().collect(maxBy(comparing(Person::getAge)));
Optional optional = list.stream().max(comparing(Person::getAge));
joining 连接字符串
String s = list.stream().map(Person::getName).collect(joining());
String s = list.stream().map(Person::getName).collect(joining(","));
groupingBy 分组
Map> map = list.stream().collect(groupingBy(Person::getAge));
按照年龄 age 分组,年龄相同的归为一组
多级分组
Map>> map = list.stream().collect(groupingBy(Person::getAge, groupingBy(...)));
按组聚合
Map map = list.stream().collect(groupingBy(Person::getAge, summingInt(Person::getAge)));
partitioningBy 分区
分区按照 true 和 false 来分
根据年龄是否小于等于20来分区
Map> map = list.stream().collect(partitioningBy(p -> p.getAge() <= 20));
list.parallelStream() 并行流
流的可分解性
ArrayList 和 LinkedList, 前者在分解方面占优
性能
Stream 的性能可能会低于传统的循环或者迭代器,甚至会低很多。
创建流的开销 流只能迭代一次 重复创建流 box unbox
函数式编程 主要是为了提高编码开发效率 及 增强代码可读性
Java performance tutorial – How fast are the Java 8 streams?
https://jaxenter.com/java-performance-tutorial-how-fast-are-the-java-8-streams-118830.html
上一篇
下一篇
会计学习指南
Java8 parallelStream 并行处理实例及注意点
Java8新特性要点
springboot2 @RequestBody注解使用说明
边缘计算要点
詹姆斯写给伦纳德的一封信