Java8中List去掉重復對象方法


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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM