==运算符在Java检查内存地址中的角色
直到今天,我一直相信两个具有相同哈希代码的对象意味着它们具有相同的内存位置。但下面的代码讲述了一个完全不同的故事: 学生实体: 公立班学生实行可比性{==运算符在Java检查内存地址中的角色,java,hashmap,equals,hashcode,Java,Hashmap,Equals,Hashcode,直到今天,我一直相信两个具有相同哈希代码的对象意味着它们具有相同的内存位置。但下面的代码讲述了一个完全不同的故事: 学生实体: 公立班学生实行可比性{ int id; int marks; String Subject; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getMarks() { return marks; } public v
int id;
int marks;
String Subject;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getMarks() {
return marks;
}
public void setMarks(int marks) {
this.marks = marks;
}
public String getSubjects() {
return Subject;
}
public void setSubject(String subject) {
Subject = subject;
}
public Student() {
}
public Student(int id, String subject, int marks) {
super();
this.id = id;
this.marks = marks;
Subject = subject;
}
@Override
public int compareTo(Student o) {
if (this.getId()>(o.getId()))
return 1;
if (this.getId()<(o.getId()))
return -1;
return 1;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((Subject == null) ? 0 : Subject.hashCode());
result = prime * result + id;
result = prime * result + marks;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (Subject == null) {
if (other.Subject != null)
return false;
} else if (!Subject.equals(other.Subject))
return false;
if (id != other.id)
return false;
if (marks != other.marks)
return false;
return true;
}
}
int-id;
整数标记;
字符串主题;
公共int getId(){
返回id;
}
公共无效集合id(内部id){
this.id=id;
}
公共整数getMarks(){
返回标记;
}
公共无效设置标记(整数标记){
这个。标记=标记;
}
公共字符串getSubjects(){
返回主题;
}
public void setSubject(字符串主题){
主题=主题;
}
公立学生(){
}
公立学生(整数id、字符串主题、整数分数){
超级();
this.id=id;
这个。标记=标记;
主题=主题;
}
@凌驾
公共内部比较(学生o){
if(this.getId()>(o.getId()))
返回1;
如果(this.getId()那么,hashCode()
总是返回内存地址并不完全正确。在您的特定情况下,您将覆盖函数以基本返回主题的hashCode
引用
您的评估将显示以下输出:
stringops.Student@955a0720
这可能有点令人困惑,因为这实际上不是裸内存地址,而是对对象的toString()
方法的调用
toString
:
getClass().getName() + '@' + Integer.toHexString(hashCode())
因此,事实上,这两个对象具有不同的内存位置,但是因为覆盖了hashCode()
,所以无法看到它们。此外,也无法覆盖Java如何选择对象的内存地址(可能有些黑客除外),但无论如何,两个对象不能具有相同的地址
下次请添加更多文本,而不是截图,以增加您的问题对其他人的搜索能力。好吧,hashCode()
总是返回内存地址,这并不完全正确。在您的特定情况下,您正在覆盖函数,以基本上返回主题的hashCode
引用
您的评估将显示以下输出:
stringops.Student@955a0720
这可能有点令人困惑,因为这实际上不是裸内存地址,而是对对象的toString()
方法的调用
toString
:
getClass().getName() + '@' + Integer.toHexString(hashCode())
因此,事实上,这两个对象具有不同的内存位置,但是因为覆盖了hashCode()
,所以无法看到它们。此外,也无法覆盖Java如何选择对象的内存地址(可能有些黑客除外),但无论如何,两个对象不能具有相同的地址
下次请包含更多文本而不是屏幕截图,以增加您的问题对其他人的搜索能力。hashcode是一个int值,由hascode()方法返回
java定义hascode(),每个java类都是Object.java的一个子类,因此每个类都继承它
如果某个类的开发人员希望重写它,则由该类的开发人员决定。某个类的开发人员可以选择(尽管这是一种不好的做法)为该类的所有对象重新运行相同的常量int值
通常hascode依赖于对象的一个或多个属性的值。尽管开发人员可能会尽力返回唯一的hashcode,但(hashcode冲突)两个不同的对象最终可能是同一个hascode
一次只能为一个对象指定一个内存位置
两个不同对象(位于Memory中的两个不同地址)的哈希代码可能相同,也可能不同
还有一个相关的概念:equals契约和hascode方法。它说,如果两个对象通过调用equals返回true,那么两个对象必须具有相同的hashcode。请注意,这是一个定义的契约,但由开发类和编写hashcode方法的开发人员来遵守契约。可能会导致错误的实现在不同的hascodes中,由两个对象为equals方法返回true。hashcode是hascode()方法返回的int值
java定义hascode(),每个java类都是Object.java的一个子类,因此每个类都继承它
如果某个类的开发人员希望重写它,则由该类的开发人员决定。某个类的开发人员可以选择(尽管这是一种不好的做法)为该类的所有对象重新运行相同的常量int值
通常hascode依赖于对象的一个或多个属性的值。尽管开发人员可能会尽力返回唯一的hashcode,但(hashcode冲突)两个不同的对象最终可能是同一个hascode
一次只能为一个对象指定一个内存位置
两个不同对象(位于Memory中的两个不同地址)的哈希代码可能相同,也可能不同
还有一个相关的概念:equals契约和hascode方法。它说,如果两个对象通过调用equals返回true,那么两个对象必须具有相同的hashcode。请注意,这是一个定义的契约,但由开发类和编写hashcode方法的开发人员来遵守契约。可能会导致错误的实现在不同的hascodes中,两个对象返回true for equals方法返回的hascodes。您已经正确地识别了两个不同的对象(即,不在同一内存地址的两个对象)确实可以具有相同的哈希代码。规则是,如果两个对象通过相等,则.equals()
method,则它们应该生成相同的哈希代码。除了这一点以及“不同的对象应该尝试使用不同的哈希代码”的一般想法之外,没有要求不同位置的对象应该进行不同的哈希
不过,这是一件好事。例如,两个不同的String
对象(每个对象具有相同的字符序列)直观上应该具有相同的哈希代码,以便HashMap
可以