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());//ACADFQ
String collect = stringList.stream().distinct().collect(Collectors.joining(","));//A,C,A,D,F,Q
String 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());
});
好了,今天就总结这么多,你学到了吗?
若是觉得文章还不错,记得点赞评论加转发哦!!!