簡體   English   中英

將非基本對象添加到TreeSet時,是否必須覆蓋hashCode和equals?

[英]Is overriding hashCode and equals a necessity when adding non-primitive objects to a TreeSet?

我正在關注使用TreeSet和Comparable接口更好地理解自然排序的教程。

本教程告訴我,要將非原始自定義對象添加到Set中,我需要實現equals()hashCode() 但是,即使沒有實現這些方法,我也能夠編譯和運行代碼(如下所示)。 我正在將IntelliJ與Java 8配合使用。

使用TreeSet(SortedSet接口)和自然排序時,是否必須重寫equals()hashCode()

class My_Person implements Comparable<My_Person>{
    private String name;

    public My_Person(String name) {
        this.name = name;
    }

    public String toString() {
        return name;
    }

//    @Override
//    public boolean equals(Object o) {
//        if (this == o)
//            return true;
//        if (o == null || getClass() != o.getClass())
//            return false;
//        My_Person my_person = (My_Person) o;
//        return Objects.equals(name, my_person.name);
//    }
//
//    @Override
//    public int hashCode() {
//        return Objects.hash(name);
//    }

    @Override
    public int compareTo(My_Person person) {
        return name.compareTo(person.name);
    }
}

public class NaturalOrdering {

    public static void main(String[] args) {

        List<My_Person> list = new ArrayList<>();
        Set<My_Person> set = new TreeSet<>();   

        addElement(list);
        addElement(set);

        Collections.sort(list);

        showElement(list);
        System.out.println("\n");
        showElement(set);

    }


    private static void addElement(Collection<My_Person> collection) {
        collection.add(new My_Person("Joe"));
        collection.add(new My_Person("Sue"));
        collection.add(new My_Person("Juliet"));
        collection.add(new My_Person("Clare"));
        collection.add(new My_Person("Mike"));
    }


    private static void showElement(Collection<My_Person> collection) {
        for(My_Person element: collection) {
            System.out.println(element);
        }
    }
}

這取決於您對平等的要求。 如果不重寫equalshashCode ,則兩個對象只有且相同時才被定義為相等(即,相同的對象)。 如果您需要其他一些相等性定義,則必須重寫方法。

這不是“絕對必要的”,但是如果您不這樣做,則可能會得到意外的/錯誤的輸出。 因此,如果您不覆蓋它們,有時它可能仍然可以工作,但是也可能失敗。 因此,為了安全起見,最好將其覆蓋。 如果您需要檢查相等性,它將失敗。 但是,如果您只關心按compareTo方法中定義的邏輯對存儲對象進行排序,那么我認為無需重寫equals或hashcode。

TreeSet或與此相關的任何Set都不需要它。 但是Set本質上是唯一對象的集合。 對於原始類型,Java有辦法知道兩個對象是否相同。 對於非原始用戶,用戶必須告訴Java如何知道兩個對象是否相同,並且方法是重寫equals和由Set#add方法調用以確定要添加的對象的hashcode方法是否已存在於集合中。 因此,如果需要在Set中使用功能獨特的對象,則應實現equalshashcode方法。 希望這可以幫助。 這是對同一主題的不錯的閱讀

您具有TreeSet的源代碼(以及TreeSet在后台使用的TreeMap)。 您可以清楚地看到TreeSet(和TreeMap)依靠compareTo()而不是hashCode()。

另一方面,HashSet(以及HashSet在后台使用的HashMap)確實使用hashCode()和equals()。 考慮到它們分別命名為“ 哈希集”和“ 哈希圖”,這並不奇怪。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM