在将非原始对象添加到TreeSet时,是否重写hashCode并且等于必要性?

时间:2015-12-27 18:30:48

标签: java treeset

我遵循教程,使用TreeSet和Comparable接口更好地理解自然排序。

教程告诉我,要将非原始自定义对象添加到集合,我需要实现equals()hashCode()。但是,即使没有实现这些方法,我也能够编译和运行代码(如下所示)。我在Java 8中使用IntelliJ。

在使用TreeSets(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);
        }
    }
}

4 个答案:

答案 0 :(得分:0)

这取决于您对平等的要求。如果不覆盖equalshashCode,则当且仅当两个对象相同时(即同一对象),才将两个对象定义为相等。如果您需要其他一些相等的定义,则必须覆盖这些方法。

答案 1 :(得分:0)

这不是绝对必要的&#34;,但如果你不这样做,你可能会得到意外/错误的输出。因此,如果你不覆盖它们,它有时可能仍然有效,但它也可能失败。所以只是为了安全,更好地覆盖它。 如果您需要检查相等性,它将失败。但是如果您只关心在compareTo方法中根据您自己定义的逻辑对存储对象进行排序,那么我认为不需要重写equals或hashcode。

答案 2 :(得分:0)

TreeSet不需要它或任何Set。但Set本质上是独特对象的集合。对于原始类型,Java有办法知道两个对象是否相同。对于非原始用户,必须告诉Java如何知道两个对象是否相同,以及如何覆盖由Set#add方法调用的equalshashcode方法来确定被添加的对象已经存在于集合中。因此,如果您需要在集合中使用功能唯一对象,则应实施equalshashcode方法。希望这可以帮助。关于同一主题的This is a good read

答案 3 :(得分:0)

您拥有TreeSet的源代码(以及TreeSet在引擎盖下使用的TreeMap)。您可以清楚地看到TreeSet(和TreeMap)依赖于compareTo()而不是hashCode()。

另一方面,HashSet(以及HashSet在引擎盖下使用的HashMap)确实使用hashCode()和equals()。考虑到它们被命名为哈希设置和哈希地图,这并不奇怪。