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,可以達到一樣的效果。