Java 将非基本对象添加到树集时,重写hashCode和等于必须吗?
为了更好地理解自然排序,我将遵循一个教程,使用TreeSet和类似的界面 本教程告诉我,要将非基本自定义对象添加到集合中,我需要实现Java 将非基本对象添加到树集时,重写hashCode和等于必须吗?,java,treeset,Java,Treeset,为了更好地理解自然排序,我将遵循一个教程,使用TreeSet和类似的界面 本教程告诉我,要将非基本自定义对象添加到集合中,我需要实现equals()和hashCode()。然而,即使没有实现这些方法,我也能够编译和运行代码(如下所示)。我将IntelliJ与Java8一起使用 在使用TreeSet(SortedSet接口)和自然排序时,是否绝对需要重写equals()和hashCode() class My_Person implements Comparable<My_Person>
equals()
和hashCode()
。然而,即使没有实现这些方法,我也能够编译和运行代码(如下所示)。我将IntelliJ与Java8一起使用
在使用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);
}
}
}
class My_Person实现可比较{
私有字符串名称;
公共My_Person(字符串名称){
this.name=名称;
}
公共字符串toString(){
返回名称;
}
//@覆盖
//公共布尔等于(对象o){
//if(this==o)
//返回true;
//如果(o==null | | getClass()!=o.getClass())
//返回false;
//我的人我的人=(我的人)o;
//返回Objects.equals(name,my_person.name);
// }
//
//@覆盖
//公共int hashCode(){
//返回Objects.hash(name);
// }
@凌驾
公共int比较(我的人){
返回name.compareTo(person.name);
}
}
公共级自然保护{
公共静态void main(字符串[]args){
列表=新的ArrayList();
Set=新树集();
附录(列表);
增件(套);
集合。排序(列表);
showElement(列表);
System.out.println(“\n”);
展示元素(套);
}
专用静态void addElement(集合){
收藏。添加(新的My_Person(“Joe”));
收藏。添加(新的My_Person(“Sue”));
收藏。添加(新的My_Person(“朱丽叶”);
收藏。添加(新的My_Person(“Clare”);
收藏。添加(新的My_Person(“Mike”));
}
私有静态void showElement(集合){
对于(My_Person元素:集合){
系统输出打印项次(元素);
}
}
}
这取决于您对平等的要求。如果不重写equals
和hashCode
,则两个对象定义为相等当且仅当它们相同时(即相同的对象)。如果需要其他相等定义,则必须重写这些方法 这不是“绝对必要的”,但如果不这样做,您可能会得到意外/错误的输出。因此,如果不覆盖它们,它有时可能仍然有效,但也可能失败。所以为了安全起见,最好把它盖上。
如果您需要检查相等性,它将失败。但若您只关心按照自己在compareTo方法中定义的逻辑对存储对象进行排序,那个么我认为并没有必要重写equals或hashcode 这不是TreeSet或任何集合所要求的。但布景本质上是独特对象的集合。对于基本类型,Java有办法知道两个对象是否相同。对于非原语用户,必须告诉Java如何知道两个对象是否相同,方法是重写
equals
和hashcode
方法,方法调用这些方法来确定要添加的对象是否已经存在于集合中。因此,如果您需要集合中具有唯一功能的对象,则应该实现equals
和hashcode
方法。希望这有帮助。关于同一个话题 您有TreeSet的源代码(以及TreeSet在引擎盖下使用的TreeMap)。您可以清楚地看到TreeSet(和TreeMap)依赖于compareTo(),而不是hashCode()
另一方面,HashSet(以及HashSet在引擎盖下使用的HashMap)确实使用hashCode()和equals()。考虑到它们被命名为HashSet和HashMap,这并不奇怪。根据Joshua Bloch在《有效Java》第3章中制定的规则,您应该始终覆盖对象的equals和hashcode。这一切都取决于您对像
新My_Person(“Joe”)这样的东西的期望。equals(新建My_Person(“Joe”))
返回。两个同名的人是否应该彼此相等?对象始终是非基本对象。因此使用术语“非基本对象”我认为总的来说,重写equals和hashCode比不重写更好、更安全。Thanks@Tiny我可能有点打错了,但你的陈述绝对没有任何价值!它是HashSet
所要求的,因为Java8的HashMap
在出现时使用自然顺序是散列冲突。这打破了一般合同,但事实确实如此。@chrylis我理解你的评论,我的回答对问题中提到的问题更为严格。但是,即使没有实现这些方法,我也能够编译和运行代码。因此,这是对为什么代码仍然编译和运行的解释。