JDK 8 新特性:Stream
文章目录
JDK 8 新特性:Stream
Lambda
参考文档: java.util.stream
Lambda也是一种匿名方法,将方法作为参数进行传递的编程思想
优点:代码简洁
缺点:可读性差;不便调试,可以合理使用换行来方便调试;JDK8以后支持
Stream
是一系列的元素,串行
管道
是一系列的聚合操作
管道源:是一个list,或者一个集合
中间操作:每个中间操作都会返回一个Stream,不会真正进行操作(”懒“操作)
结束操作:当这个操作执行后,流就被使用结束,无法继续再操作。结束操作是流的最后一个操作,返回的结果不是Stream,可以返回int、float、String、Collection等。结束操作才是真正的遍历行为,在遍历的时候执行中间操作。
管道源
将Collection转为管道源一般使用Stream() 方法
List<Hero> heroes = new ArrayList<>();
// heroes.stream()
// 将Collection转为管道源
Hero[] hs= new Hero[10];
// Arrays.stream(hs) | Stream.of(hs)
// 数组转为管道源
中间操作
操作 | 含义 |
---|---|
filter | 匹配 |
distinct | 去除重复(根据equals判断) |
sorted | 自然排序 |
sorted(Comparator< T >) | 指定排序 |
limit | 保留 |
skip | 忽略 |
map | 转换为任意的流 |
mapToDouble | 转换为double的流 |
结束操作
操作 | 含义 |
---|---|
forEach() | 遍历每个元素 |
toArray() | 转换为数组 |
min(Comparator< T >) | 取最小的元素 |
max(Comparator< T >) | 取最大的元素 |
count() | 计数 |
findFirst() | 第一个元素 |
Stream Api常用操作
List to List
1. List< Object > To List< Object >
-
从List集合对象中取某个字段作为数据集合 List< String>
List<CodeType> list = new ArrayList<>(); CodeType c1 = new CodeType(); c1.setCode("1"); c1.setName("字符串"); list.add(c1); CodeType c2 = new CodeType(); c2.setCode("2"); c2.setName("数组"); list.add(c2); List<String> strings = list.stream() // 取name作为新的数组的元素 .map(CodeType::getName) .collect(Collectors.toList());
-
从List集合对象中取符合某种条件的对象 < Object>
List<CodeType> list = new ArrayList<>(); CodeType c1 = new CodeType(); c1.setCodeType("001"); c1.setCode("1"); c1.setName("字符串"); list.add(c1); CodeType c2 = new CodeType(); c2.setCodeType("002"); c2.setCode("2"); c2.setName("数组"); list.add(c2); List<CodeType> collect = list.stream() // 取非空元素 .filter(Objects::nonNull) // 取 CodeType == “001” 的对象 .filter(r -> "001".equals(r.getCodeType())) .collect(Collectors.toList());
List to Map
1. List< Object > To Map<String, String>
-
取List对象中某两个字段作为< key, value >
List<CodeType> list = new ArrayList<>(); CodeType c1 = new CodeType(); c1.setCodeType("001"); c1.setCode("1"); c1.setName("字符串"); list.add(c1); CodeType c2 = new CodeType(); c2.setCodeType("002"); c2.setCode("2"); c2.setName("数组"); list.add(c2); CodeType c3 = new CodeType(); c3.setCodeType("001"); c3.setCode("1"); c3.setName("整形1"); list.add(c3); CodeType c4 = new CodeType(); c4.setCodeType("001"); c4.setCode("1"); c4.setName("整形2"); list.add(c4); // error // java.lang.IllegalStateException: Duplicate key 字符串 // Map<String, String> collect1 = list.stream() // .filter(Objects::nonNull) // .collect(Collectors.toMap(CodeType::getCode, CodeType::getName)); // 改进 // (first, next) -> first) 相同的key,取第一个 // (first, next) -> next) 相同的key 取最后一个 Map<String, String> collect2 = list.stream() .filter(Objects::nonNull) .collect(Collectors.toMap(CodeType::getCode, CodeType::getName, (first, next)->first));
2. List< Object > To Map<String, Object>
-
取List对象中某字段作为key,对象本身作为value
List<CodeType> list = new ArrayList<>(); CodeType c1 = new CodeType(); c1.setCodeType("001"); c1.setCode("1"); c1.setName("字符串"); list.add(c1); CodeType c2 = new CodeType(); c2.setCodeType("002"); c2.setCode("2"); c2.setName("数组"); list.add(c2); CodeType c3 = new CodeType(); c3.setCodeType("001"); c3.setCode("1"); c3.setName("整形1"); list.add(c3); CodeType c4 = new CodeType(); c4.setCodeType("001"); c4.setCode("1"); c4.setName("整形2"); list.add(c4); // error // java.lang.IllegalStateException: Duplicate key my.demo.entity.CodeType@54a097cc // Map<String, CodeType> collect1 = list.stream() // .filter(Objects::nonNull) // .collect(Collectors.toMap(CodeType::getCode, x -> x)); // 改进 // (first, next) -> first) 相同的key,取第一个 // (first, next) -> next) 相同的key 取最后一个 Map<String, CodeType> collect2 = list.stream() .filter(Objects::nonNull) .collect(Collectors.toMap(CodeType::getCode, x -> x, (first, next)->first));
3. List< Object > To Map<String, List< Object>>
-
取List对象中某字段作为分组依据key,该字段相同的对象组成一个List作为value
List<CodeType> list = new ArrayList<>(); CodeType c1 = new CodeType(); c1.setCodeType("001"); c1.setCode("1"); c1.setName("字符串"); list.add(c1); CodeType c2 = new CodeType(); c2.setCodeType("002"); c2.setCode("2"); c2.setName("数组"); list.add(c2); CodeType c3 = new CodeType(); c3.setCodeType("001"); c3.setCode("1"); c3.setName("整形"); list.add(c3); // 根据codeType来分组,相同codeType合成一个List Map<String, List<CodeType>> listMap = list.stream() .filter(Objects::nonNull) // groupingBy以某个字段作为分组 // mapping传入两个参数:对象、操作 .collect(Collectors.groupingBy(CodeType::getCodeType, Collectors.mapping(x -> x, Collectors.toList()))); Map<String, List<CodeType>> listMap2 = list.stream() .filter(Objects::nonNull) // groupingBy以某个字段作为分组 .collect(Collectors.groupingBy(CodeType::getCodeType));
Map to List
1. Map<String, Object> To List< Object>
-
取Map的key作为一个新的List
Map<String, String> map = new HashMap<>(); // Convert all Map keys to a List List<String> result = new ArrayList(map.keySet()); // Java 8, Convert all Map keys to a List List<String> result3 = map.keySet().stream() .collect(Collectors.toList());
-
取Map的value作为一个新的List
Map<String, String> map = new HashMap<>(); // Convert all Map values to a List List<String> result2 = new ArrayList(map.values()); // Java 8, Convert all Map keys to a List List<String> result3 = map.values().stream() .collect(Collectors.toList());