stream 流的使用技巧总结,这些你必须知道
1、简述
我们都知道Stream,是jdk8的一大新特性,极大的提高了道友们的开发效率(用过的道友都知道的),也使我们的代码看起来也更加地简洁,但Stream中除了Lambda表达式,另一块就是函数编程了,这块对于刚开始使用Stream的道友们来说,就得开始头疼抓狂了;别担心,下面我们就来总结一下常用技巧。
Stream有串行流stream与并行流parallelStream:
userList.stream()
userList.parallelStream()
一、基本类型集合
定义一个整型集合与字符串集合
List<Integer> integerList = new ArrayList<>(); integerList.add(12); integerList.add(3); integerList.add(3); integerList.add(2);List<String> stringList = new ArrayList<>(); stringList.add("A"); stringList.add("C"); stringList.add("A"); stringList.add("D"); stringList.add("F"); stringList.add("Q");
1、统计所有元素之和
int sum = integerList.stream().mapToInt(item -> item).sum();//结果:20//或者将结果直接转为long型long sum = integerList.stream().mapToLong(item -> item).sum();//20
2、剔除重复项后求和
int sum = integerList.stream().distinct().mapToInt(item -> item).sum(); //17
3、字符串去重
List<String> collect = stringList.stream().distinct().collect(Collectors.toList())
4、遍历每个元素
stringList.forEach(item-> { // todo your things,若调用的底层方法往上抛出了异常,这里需要手动try-catch});
5、将元素拼成一个字符串
String collect = stringList.stream().distinct().collect(Collectors.joining());//ACADFQString collect = stringList.stream().distinct().collect(Collectors.joining(","));//A,C,A,D,F,QString collect = stringList.stream().distinct().collect(Collectors.joining(",", "(", ")"));//(A,C,A,D,F,Q)
6、分组后统计每组个数
Map<String, Long> collect = stringList.stream().collect(Collectors.groupingBy(item -> item, Collectors.counting()));//{Q=1, A=2, C=1, D=1, F=1}
二 、对象集合
定义对象集合(有两个重复项)
[ { "age": 10, "className": "计算机1", "sex": 0, "username": "nick10" }, { "age": 10, "className": "计算机1", "sex": 0, "username": "nick10" }, { "age": 12, "className": "计算机3", "sex": 0, "username": "nick12" }, { "age": 13, "className": "计算机2", "sex": 1, "username": "nick13" }, { "age": 14, "className": "计算机2", "sex": 0, "username": "nick14" }, { "age": 15, "className": "计算机2", "sex": 1, "username": "nick15" }, { "age": 16, "className": "计算机3", "sex": 0, "username": "nick16" }, { "age": 17, "className": "计算机3", "sex": 1, "username": "nick17" }, { "age": 19, "className": "计算机1", "sex": 1, "username": "nick19" }, { "age": 19, "className": "计算机1", "sex": 1, "username": "nick19" }]List<User> userList = new ArrayList<>(); //省略add方法
//按班级分类收集Map<String, List<User>> listMap = userList.stream().collect(Collectors.groupingBy(User::getClassName, Collectors.toList()));//按班级分类收集(只保留一个元素)//若你确定你的集合中需要作为key的元素不会出现重复,则可以用以下方式:Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getClassName, Function.identity()));//若你不确定,你必须使用以下方式:Map<String, User> userMap = userList.stream() .collect(Collectors.toMap(User::getClassName, Function.identity(), (value1, value2) -> value2));//后面使用value2表示保留最后一个,使用value1保留第一个//根据 username 剔除重复项List<User> users = userList.stream() .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<User>(Comparator.comparing(User::getUsername))), ArrayList::new));
三、特别注意点:
使用并行流parallelStream,千万不能使用toMap方法,toMap使用的是HashMap,得用toConcurrentMap:
//错误示例Map<String, User> userMap = userList.parallelStream().collect(Collectors.toMap(User::getClassName, Function.identity()));//正确示例Map<String, User> userMap = userList.parallelStream().collect(Collectors.toConcurrentMap(User::getClassName, Function.identity()));
也不能使用ArrayList,的用Vector:
List<String> usernames = new ArrayList<>();//返回结果顺序不变userList.forEach(user -> { usernames.add(user.getUsername());});//或者,返回结果顺序不变,虽然用的并行流List<String> collect1 = userList.parallelStream().map(User::getUsername).collect(Collectors.toList());//返回结果顺序改变userList.parallelStream().forEach(user -> { usernames.add(user.getUsername()); });
好了,今天就总结这么多,你学到了吗?
若是觉得文章还不错,记得点赞评论加转发哦!!!
作者:技术指北
链接:https://www.jianshu.com/p/3eb86d3890d6
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。