lambda常用总结

排序

在用到Stream做排序时,如果数据存在null值就会抛出空指针异常,可能最理想的方式排除空值的内容进行排序,最后将空值的内容排在最后或者最前面。

下面的示例是使用对象的时间进行排序,如果时间为空则将其排在列表最后面:

1
2
3
4
List<Change> changes = changeList.stream()
.sorted(Comparator.comparing(
Change::getDate, Comparator.nullsFirst(Date::compareTo)).reversed())
.collect(Collectors.toList());

去重

在很多时候会用到去重,对于实体列表的去重,在没有重写equals和hashCode方法时,要通过Lambda去重比较麻烦和不友好,因为Streamdistinct()方法不支持形如distinct(Change::getDid)这种形式的去重,我自己总结论一个稍微好一点的方式:

1
2
3
4
5
6
7
List<Change> uniqueList = opList
.stream()
.collect(Collectors.groupingBy(Change::getDid))
.values()
.stream()
.flatMap(list -> list.stream().limit(1))
.collect(Collectors.toList());

distinct

distinct是基于hashCodeequals工作的,且不提供按照属性对对象列表进行去重的直接实现。若想要按照对象的属性,若对对象去重需要重写对象的hashCode方法和equals方法;

若对对象列表进行去重,可以通过以下方法来实现,distinctByKey()方法返回一个使用ConcurrentHashMap来维护先前所见状态的 Predicate实例,结合filter来进行去重:

1
2
3
4
5
6
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

list.stream().filter(distinctByKey(b -> b.getName()));