概述
Stream 作为 Java 8 的一大亮点,一个高级的迭代器(Iterator),数据只能遍历一次,用于简化代码。 下述几种工作常用的stream
常用方法
- map 单组映射
- flatmap 多组映射
- filter 过滤
- Collect 收集
- groupingBy 分组
- sort 排序
- reduce 求和
- distinct
获取对象值的方法
1. AClass::getField
2. o->o.getField()
3. o->{
return o.getField
}
Stream结果数据处理
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。Optional 类的引入很好的解决空指针异常。
Optional可以被collect收集出多个,也可以被findFirst收集出一个
List<String> names2 = list.stream().map(o->o.getName()).collect(Collectors.toList());
String name3 = list.stream().map(o->o.getName()).findFirst().orElse(null);
具体操作
map 映射
有人说这个是归类,但其实没到归类这一步,只是一种映射规则,你可以映射出一个基本类型、也可以映射出一个自定义对象。
List<User> list = new ArrayList<>();
list.add(new User(1,"zhangsan"));
list.add(new User(2,"lisi"));
List<String> names = list.stream().map(User::getName).collect(Collectors.toList());
List<String> names2 = list.stream().map(o->o.getName()).collect(Collectors.toList());
filter 过滤条件
filter中可以写多个条件 用&& 或者|| 连接,只需要最终是一个boolean类型的值
List<User> list = new ArrayList<>();
list.add(new User(1,"zhangsan"));
list.add(new User(2,"lisi"));
List<User> names = list.stream().filter(o->o.getId()>1).collect(Collectors.toList());
groupingBy 分组
- 按对象一个字段分组
List<User> list = new ArrayList<>();
list.add(new User(1,"zhangsan"));
list.add(new User(2,"lisi"));
Map<String, List<User>> collect = list.stream().collect(Collectors.groupingBy(User::getName));
- 按对象中多个字段分组 需要先新建对象,然后重写UserGrouping的hashCode和equal
List<User> list = new ArrayList<>();
list.add(new User(1,"zhangsan",10));
list.add(new User(2,"lisi",10));
Map<UserGrouping, List<User>> collect = list.stream()
.collect(
Collectors.groupingBy(
o->new UserGrouping(o.getName(),o.getAge())
)
);
sorted 排序
- 按对象一个字段排序
List<User> list = new ArrayList<>();
list.add(new User(1,"zhangsan",10));
list.add(new User(2,"lisi",10));
list.stream().sorted(Comparator.comparing(User::getName)).collect(Collectors.toList());
- 按对象多个字段排序
List<User> list = new ArrayList<>();
list.add(new User(1,"zhangsan",10));
list.add(new User(2,"lisi",10));
list.stream().sorted(Comparator.comparing(User::getName)).collect(Collectors.toList());
list.stream().sorted(
Comparator.comparing(User::getName,(x,y)->{
if(x == null && y != null){
return 1;
}else if(x !=null && y == null){
return -1;
}else if(x == null && y == null){
return -1;
}else{
}
return 0;
}
)
.thenComparing(Comparator.comparing(User::getAge))
).collect(Collectors.toList());
- 但是我觉得可以用原本List的sort
list.sort(new Comparator<User>(){
@Override
public int compare(User o1, User o2) {
if (o1.getAge()>o2.getAge()) {
return o1.getAge()-o2.getAge();
} else if (o1.getAge()==o2.getAge()) {
if (o1.getName().hashCode()>o2.getName().hashCode()) {
return 1;
}
}
return 0;
}
});
distinc
- 去重,根据hashCode和equal去重。
List<User> userList = list.stream().distinct().collect(Collectors.toList());
- 根据特定的字段去重复
List<User> collect = users.stream().collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getUserName()))),
ArrayList::new));
但是这种就不能根据多个字段去重复,如果要根据多个字段去重复应该用对象的形式把hashCode和equal写好,然后用第一种方式去重
flatMap
扁平化映射
Map<String ,List<User>> map = new HashMap<>();
Set<Entry<String, List<User>>> entrySet = map.entrySet();
ist<User> collect = entrySet.stream().flatMap(o->o.getValue().stream())).collect(Collectors.toList());
利用Collect做List转Map
List<User> list = new ArrayList<>();
Map<String, User> oldDetailMap = list.stream().collect(
Collectors.toMap(detail -> detail.getCode(),
Function.identity(), (key1, key2) -> key2));
去重复
Map<Integer, Student> map = list.stream().collect(Collectors.toMap(Student::getId, student -> student,(v1,v2)->v1));
list To map 去重复
Map<Long, User> collect = listAll.stream() .collect(Collectors.toMap(o -> o.getid(), Function.identity(), (o, n) -> o));