1. List中简单元素去重(String等) public List<String> removeStringListDupli(List<String> stringList) { Set<String> set = new LinkedHashSet<>(); set.addAll(stringList); stringList.clear(); stringList.addAll(set); return stringList; } 或使用Java8的写法: List<String> unique = list.stream().distinct().collect(Collectors.toList()); 1 2. List中对象去重 比如现在有一个 Person类: public class Person { private Long id; private String name; public Person(Long id, String name) { this.id = id; this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + '}'; } } 重写Person对象的equals()方法和hashCode()方法: @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (!id.equals(person.id)) return false; return name.equals(person.name); } @Override public int hashCode() { int result = id.hashCode(); result = 31 * result + name.hashCode(); return result; } 下面对象去重的代码: public static void main(String[] args) { Person p1 = new Person(1l, "jack"); Person p2 = new Person(3l, "jack chou"); Person p3 = new Person(2l, "tom"); Person p4 = new Person(4l, "hanson"); Person p5 = new Person(5l, "胶布虫"); List<Person> persons = Arrays.asList(p1, p2, p3, p4, p5, p5, p1, p2, p2); List<Person> personList = new ArrayList<>(); // 去重 persons.stream().forEach(p -> { if (!personList.contains(p)) { personList.add(p); } }); System.out.println(personList); } List 的contains()方法底层实现使用对象的equals方法去比较的,其实重写equals()就好,但重写了equals最好将hashCode也重写了。 3. 根据对象的属性去重 下面要根据Person对象的id去重,那该怎么做呢? 写一个方法吧: public static List<Person> removeDupliById(List<Person> persons) { Set<Person> personSet = new TreeSet<>((o1, o2) -> o1.getId().compareTo(o2.getId())); personSet.addAll(persons); return new ArrayList<>(personSet); } 通过Comparator比较器,比较对象属性,相同就返回0,达到过滤的目的。 再来看比较炫酷的Java8写法: public static void main(String[] args) { // 根据id去重 List<Person> unique = persons.stream().collect(collectingAndThen( toCollection(() -> new TreeSet<>(comparingLong(Person::getId))), ArrayList::new) ); } public static void main(String[] args) { // 根据name去重 List<Person> unique = persons.stream().collect(Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))), ArrayList::new)); unique.forEach(p -> System.out.println(p)); } persons这个list的streamAPI的聚合操作collect可以让我们只关注结果,而collect方法里的collectingAndThen又是属 于 java.util.stream.Collector,collectingAndThen操作的解释是:先执行前面的操作,然后执行第二部操作后输出结果。 第一步操作就是Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))); 第二步就是将他输出为一个新的ArrayList; 第一步操作里又是用到Collectors接口,这次用的是toCollection方法,就是将方法里的函数或者参数转化为一个collection集合,这里,我们是将Comparator.comparing(Person::getName)转化为一个collection,这个collection是一个TreeSet。也就是有序的。因为我们需要去掉重复的值,这个set可以做到,而我们又要保持转化出来的collection依旧有序,所以使用的是一个TreeSet。 Comparator.comparing(Person::getName)这里呢,又用到了java.util.Comparator接口,这个接口倒是挺常用的。使用的是他的comparing方法,也就是比较参数的值是否相同,里面用到的是java8的新特性lambda表达式, :: 其实和.没太大区别,举个例子,最常用的System.out.println() 可以表达为System.out::println,可以达到一样的效果。