Java8 lambda自带的去重为 distinct() 方法,只能针对整个对象进行去重
对数组[1, 1, 1, 6, 7]去重后得到的结果为[1, 6, 7]
代码如下
@Test
public void distinctTest1() {
List<Integer> arr = Arrays.asList(1, 1, 1, 6, 7);
List<Integer> distinctNumbers = arr.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctNumbers); // 1, 6, 7
}
如果我们想要对对象进行条件去重,有什么好的方法呢?
方法一 (使用自定义方法加filter)
一、定义一个方法
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null;
}
二、使用filter进行去重
@Test
public void distinctTest2() {
List<User> users = new LinkedList<>();
users.add(new User("小明", 18));
users.add(new User("小红", 18));
users.add(new User("小兰", 16));
users.add(new User("小兰", 17));
users.add(new User("小兰", 17));
// 根据 name 进行去重
List<User> distinctUsers1 = users.stream()
.filter(distinctByKey(User::getName))
.collect(Collectors.toList());
System.out.println(distinctUsers1);
// 执行结果 [{"小明", 18}, {"小红", 18}, {"小兰", 16}]
// 根据 name + age 进行去重
List<User> distinctUsers2 = users.stream()
.filter(distinctByKey(item->item.getName + item.getAge))
.collect(Collectors.toList());
System.out.println(distinctUsers2);
// 执行结果[{"小明", 18}, {"小红", 18}, {"小兰", 16}, {"小兰", 17}]
}
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null;
}
方法二 使用自带的 collectors 和 treeset 实现去重
@Test
public void distinctTest2() {
List<User> users = new LinkedList<>();
users.add(new User("小明", 18));
users.add(new User("小红", 18));
users.add(new User("小兰", 16));
users.add(new User("小兰", 17));
users.add(new User("小兰", 17));
// 根据 name 进行去重
List<User> userList = users.stream()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))),
ArrayList::new)
);
System.out.println(distinctUsers1);
// 执行结果 [{"小明", 18}, {"小红", 18}, {"小兰", 16}]
// 根据 name + age 进行去重
List<User> userList = users.stream()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item->item.getName + item.getAge))),
ArrayList::new)
);
System.out.println(distinctUsers2);
// 执行结果[{"小明", 18}, {"小红", 18}, {"小兰", 16}, {"小兰", 17}]
}