我遵循教程,使用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);
}
}
}
答案 0 :(得分:0)
这取决于您对平等的要求。如果不覆盖equals
和hashCode
,则当且仅当两个对象相同时(即同一对象),才将两个对象定义为相等。如果您需要其他一些相等的定义,则必须覆盖这些方法。
答案 1 :(得分:0)
这不是绝对必要的&#34;,但如果你不这样做,你可能会得到意外/错误的输出。因此,如果你不覆盖它们,它有时可能仍然有效,但它也可能失败。所以只是为了安全,更好地覆盖它。 如果您需要检查相等性,它将失败。但是如果您只关心在compareTo方法中根据您自己定义的逻辑对存储对象进行排序,那么我认为不需要重写equals或hashcode。
答案 2 :(得分:0)
TreeSet不需要它或任何Set。但Set本质上是独特对象的集合。对于原始类型,Java有办法知道两个对象是否相同。对于非原始用户,必须告诉Java如何知道两个对象是否相同,以及如何覆盖由Set#add方法调用的equals
和hashcode
方法来确定被添加的对象已经存在于集合中。因此,如果您需要在集合中使用功能唯一对象,则应实施equals
和hashcode
方法。希望这可以帮助。关于同一主题的This is a good read。
答案 3 :(得分:0)
您拥有TreeSet的源代码(以及TreeSet在引擎盖下使用的TreeMap)。您可以清楚地看到TreeSet(和TreeMap)依赖于compareTo()而不是hashCode()。
另一方面,HashSet(以及HashSet在引擎盖下使用的HashMap)确实使用hashCode()和equals()。考虑到它们被命名为哈希设置和哈希地图,这并不奇怪。