java 按照对象的某个属性去重

按照集合元素对象属性去重

实际的工作中,按照集合元素对象整体去重的应用的比较少,更多的是要求我们按照元素对象的某些属性进行去重。

TreeSet实现Comparator接口

为TreeSet实现Comparator接口,如果我们希望按照Player的name属性进行去重,就去在Comparator接口中比较name。
下文中写了两种实现Comparator接口方法:

  • 方法引用:Comparator.comparing(Player::getName)
@Test
void testRemove5() {
 //Set playerSet = new TreeSet<>((o1, o2) -> o1.getName().compareTo(o2.getName()));
 Set<Player> playerSet = new TreeSet<>(Comparator.comparing(Player::getName));
 playerSet.addAll(playerList);
 
 /*new ArrayList<>(playerSet).forEach(player->{
 System.out.println(player.toString());
 });*/
 //将去重之后的结果打印出来
 new ArrayList<>(playerSet).forEach(System.out::println);
}
  • lambda表达式:(o1, o2) -> o1.getName().compareTo(o2.getName())
    首先用stream()把list集合转换成流,然后用collect及toCollection把流转换成集合
@Test
void testRemove6() {
 List<Player> newList = playerList.stream().collect(Collectors
  .collectingAndThen(
   Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Player::getName))),
   ArrayList::new));
 
 newList.forEach(System.out::println);
}

filter方法

首先我们定义一个谓词Predicate用来过滤,过滤的条件是distinctByKey。谓词返回ture元素保留,返回false元素被过滤掉。
当然我们的需求是过滤掉重复元素。我们去重逻辑是通过map的putIfAbsent实现的。putIfAbsent方法添加键值对,如果map集合中没有该key对应的值,则直接添加,并返回null,如果已经存在对应的值,则依旧为原来的值。
如果putIfAbsent返回null表示添加数据成功(不重复),如果putIfAbsent返回value(value==null :false),则满足了distinctByKey谓词的条件元素被过滤掉。

@Test
void testRemove7() {
 List<Player> newList = new ArrayList<>();
 playerList.stream().filter(distinctByKey(p -> p.getName())) //filter保留true的值
  .forEach(newList::add);
 
 newList.forEach(System.out::println);
}
 
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
 Map<Object,Boolean> seen = new ConcurrentHashMap<>();
 //putIfAbsent方法添加键值对,如果map集合中没有该key对应的值,则直接添加,并返回null,如果已经存在对应的值,则依旧为原来的值。
 //如果返回null表示添加数据成功(不重复),不重复(null==null :TRUE)
 return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

这种方法虽然看上去代码量增大了,但是distinctByKey谓词方法只需要被定义一次,就可以无限复用。

利用多个属性去重

@Test
void testRemove8() {
 Set<Player> playerSet = new TreeSet<>(Comparator.comparing(o -> (o.getName() + "" + o.getAge())));
 
 playerSet.addAll(playerList);
 
 new ArrayList<>(playerSet).forEach(System.out::println);
}

你可能感兴趣的:(工作总结,java,前端,servlet)