分享两个jdk1.8中stream的小技巧
一.stream去重:
1.List元素是基本类型的包装类
List<String> list= Arrays.asList("Xiaoming","Xiaohong","Xiaogang","Xiaoming");
list.stream().distinct().forEach(e-> System.out.println(e));
List<Integer> list2= Arrays.asList(1,2,3,1);
list2.stream().distinct().forEach(e-> System.out.println(e));
stream默认去重效果如下:
2.List元素自定义对象
有如下对象
准备List:
/**
* 19-7-16、7-15、7-14、7-16
*/
List<Student> list= Arrays.asList(
new Student("小明","男",new Date(1563206400000L))
,new Student("小刚","男",new Date(1563120000000L))
,new Student("小红","女",new Date(1563033600000L))
,new Student("小明","男",new Date(1563206400000L)));
list.stream().distinct().forEach(e-> System.out.println(e));
stream默认去重效果:
并没有去重,因为第一个小明和第四个小明是不同的对象引用。将第一个小明和第四个换成同一个引用:
Student one=new Student("小明","男",new Date(1563206400000L));
List<Student> list= Arrays.asList(one
,new Student("小刚","男",new Date(1563120000000L))
,new Student("小红","女",new Date(1563033600000L))
,one);
list.stream().distinct().forEach(e-> System.out.println(e));
去重效果:
)
证明默认是判断对象引用是否相同。那如何根据对象的某个属性去重呢?
有如下自定义函数:
/**
* stream去重自定义函数
* @param keyExtractor
* @param <T>
* @return
*/
public static <T> Predicate<T> distinctByField(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>(16);
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
根据学生名字去重代码:
/**
* 19-7-16、7-15、7-14、7-16
*/
List<Student> list= Arrays.asList(
new Student("小明","男",new Date(1563206400000L))
,new Student("小刚","男",new Date(1563120000000L))
,new Student("小红","女",new Date(1563033600000L))
,new Student("小明","男",new Date(1563206400000L)));
list.stream().filter(distinctByField(e->e.getName())).forEach(e-> System.out.println(e));
自定义去重效果:
二.List
有如下自定义根据map属性排序list函数:
/**
* 自定义Map属性排序List方法
* @param map
*/
private static String comparingByBirth(Map<String, Object> map){
return map.get("birth").toString();
}
准备数据:
/**
* 19-7-15、7-14、7-16
*/
List<Map<String,Object>> list=new ArrayList<>();
Map<String,Object> map=new LinkedHashMap<>();
map.put("name","小明");
map.put("sex","男");
map.put("birth","2019-07-15");
list.add(map);
Map<String,Object> map2=new LinkedHashMap<>();
map2.put("name","小红");
map2.put("sex","女");
map2.put("birth","2019-07-14");
list.add(map2);
Map<String,Object> map3=new LinkedHashMap<>();
map3.put("name","小刚");
map3.put("sex","男");
map3.put("birth","2019-07-16");
list.add(map3);
list.stream().sorted(Comparator.comparing(Test::comparingByBirth))
.forEach(e-> System.out.println(e));
排序(默认升序)后效果:
三.总结
①排序可使用日期的字符串形式(- or /),也可以使用Date类型,但注意自定义函数返回值类型也要修改为Date
②想要排序结果为降序(在sorted中调用reversed即可):
list.stream().sorted(Comparator.comparing(Test::comparingByBirth).reversed())
.forEach(e-> System.out.println(e));
③注意去重和排序的调用方式不同
④以上两个自定义函数是网上找的,底层如何执行并不了解,有兴趣的可以自己搜一下