初始化数据
public class ListRmDuplicate {
private List<String> list;
private List<Player> playerList;
@BeforeEach
public void setup() {
list = new ArrayList<>();
list.add("kobe");
list.add("james");
list.add("curry");
list.add("zimug");
list.add("zimug");
playerList= new ArrayList<>();
playerList.add(new Player("kobe","10000")); //科比万岁
playerList.add(new Player("james","32"));
playerList.add(new Player("curry","30"));
playerList.add(new Player("zimug","27")); // 注意这里名字重复
playerList.add(new Player("zimug","18")); //注意这里名字和年龄重复
playerList.add(new Player("zimug","18")); //注意这里名字和年龄重复
}
}
@Test
void testRemove1() {
/*Set set = new HashSet<>(list);
List newList = new ArrayList<>(set);*/
//去重并排序的方法(如果是字符串,按字母表排序。如果是对象,按Comparable接口实现排序)
//List newList = new ArrayList<>(new TreeSet<>(list));
//简写的方法
List<String> newList = new ArrayList<>(new HashSet<>(list));
System.out.println( "去重后的集合: " + newList);
}
去重后的集合: [kobe, james, zimug, curry]
@Test
void testRemove2() {
List<String> newList = list.stream().distinct().collect(Collectors.toList());
System.out.println( "去重后的集合: " + newList);
}
去重后的集合: [kobe, james, curry, zimug]
//三个集合类list、newList、set,能够保证顺序
@Test
void testRemove3() {
Set<String> set = new HashSet<>();
List<String> newList = new ArrayList<>();
for (String str :list) {
if(set.add(str)){ //重复的话返回false
newList.add(str);
}
}
System.out.println( "去重后的集合: " + newList);
}
去重后的集合: [kobe, james, curry, zimug]
//优化 List、newList、set,能够保证顺序
@Test
void testRemove4() {
List<String> newList = new ArrayList<>();
for (String cd:list) {
if(!newList.contains(cd)){ //主动判断是否包含重复元素
newList.add(cd);
}
}
System.out.println( "去重后的集合: " + newList);
}
去重后的集合: [kobe, james, curry, zimug]
(o1, o2) -> o1.getName().compareTo(o2.getName())
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);
}
输出结果如下:三个zimug因为name重复,另外两个被去重。但是因为使用到了TreeSet,list中元素被重新排序。
Player{name='curry', age='30'}
Player{name='james', age='32'}
Player{name='kobe', age='10000'}
Player{name='zimug', age='27'}
@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);
}
Player{name='curry', age='30'}
Player{name='james', age='32'}
Player{name='kobe', age='10000'}
Player{name='zimug', age='27'}
@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;
}
@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);
}
原文见:List集合对象去重及按属性去重的8种方法