java8的stream使用小示例(java stream 用法)
据 JetBrains发布的2021年开发者生态系统调查,Java 8 在java使用的版本中仍然是当前最流行的版本。72%的专业开发人员使用 Java 8 作为其在java开发中主要编程语言版本。
现在已经有不少文章介绍过java8的stream,你们可以搜索学习。但是存在一部分这种现象:了解api后,但是没有经常实践的地方,久而久之又生疏了。本文默认读者了解过java8的stream,提供一些使用小示例。高手多多提提意见。
本次示例实体
public class User {
private Integer userId;
private String username;
private String idCardNum;
private Integer age;
// ....省略了构造器、getter、setter
}
1、实体字段去重
1.1 对list中对象的某个字段去重,获取这个字段的集合
List<String> idCardNums = users.stream().map(User::getIdCardNum).distinct().collect(Collectors.toList());
当然,也可以利用set的天然特性进行去重
Set<String> idCardNums = users.stream().map(User::getIdCardNum).collect(Collectors.toSet());
其中,map方法是获取你需要的字段(map中还可以做很多操作,例如组装一个新实体等等,这里就不赘述了),distinct是去重操作。
1.2 对list中对象的某个字段去重,获取去重后对象的集合
List<User> distinctUsers = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getIdCardNum))), ArrayList::new));
2 分组
2.1 根据某个字段进行分组
Map<Integer, List<User>> groupUsers = users.stream().collect(Collectors.groupingBy(User::getUserId, Collectors.toList()));
有时仅根据数据的某个字段不能满足要求,要根据业务场景对字段进行处理。现在给出一种示例:
要求分组之后每个key都是定长:
Map<String, List<User>> groupUsers = users.stream().collect(Collectors.groupingBy(v->String.format("%02d", v.getUserId()), Collectors.toList()));
2.2 根据某个字段进行分组并提取对象中的某个字段
Map<Integer, List<String>> groupUsers = users.stream().collect(Collectors.groupingBy(User::getUserId, Collectors.mapping(User::getIdCardNum, Collectors.toList())));
其中,将最后的Collectors.toList()改成Collectors.toSet()可以进一步对对象字段idCardNum进行去重处理。
3 排序
3.1 按年龄排序(Integer类型)升序排序
List<User> ageUpSortUsers = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
如果是JSONObject这类的就没法使用::进行方法调用,这里也给出示例
List<JSONObject> ageUpSortUserObjects = userObjects.stream().sorted(Comparator.comparingInt(i-> i.getIntValue("age"))).collect(Collectors.toList());
3.2 按年龄排序(Integer类型)降序排序(使用reversed()方法)
List<User> ageDownSortUsers = users.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
降序时,对JSONObject进行排序时,因为要使用reversed方法,需要对i进行强转
List<JSONObject> ageDownSortUserObjects = userObjects.stream().sorted(Comparator.comparingInt(i-> ((JSONObject)i).getIntValue("age")).reversed()).collect(Collectors.toList());
3.3 使用年龄进行降序排序,年龄相同再使用userid升序排序
List<User> sortUsers = users.stream().sorted(Comparator.comparing(User::getAge).reversed().thenComparing(User::getUserId)).collect(Collectors.toList());
3.4 取前5或者top5
使用年龄进行降序排序,年龄相同再使用userid升序排序,最后取前五条数据。那这个就简单多了,一个limit解决。
List<User> sortUsers = users.stream().sorted(Comparator.comparing(User::getAge).reversed().thenComparing(User::getUserId))。limit(5).collect(Collectors.toList());
使用年龄进行降序排序,年龄相同再使用userid升序排序,最后取年龄最大的top5。这里的top5是指年龄相同的并列一个名次,依此获取top5,实际人数>=5。
List<Integer> ageTop5s = users.stream().map(User::getAge).distinct().sorted((v1, v2) -> v2 - v1).limit(5).collect(Collectors.toList());
List<User> top5Users = users.stream().filter(v -> ageTop5s.contains(v.getAge())).sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
这里的解决方案是先获取排序依据字段的前五,再在原数据中过滤,最后排序。如果有好的方法,可以多提提,感谢。
先介绍这么多,下次再见。
[声明]:本文只有一张图片,源自JetBrains发布的调查,如有侵权,请联系我删除。