我正在更深入地学习哈希码,并认为:
1。如果重写equals(),则必须覆盖hashcode()。
2。要查找2个对象是否是同一个对象,请使用==运算符
考虑到这两个因素,在Java中我假设当== operator
用于比较如果2个实例相同或不相同时,
if(object1 == object2)
实际上在做
if(object1.hashcode() == object2.hashcode())
但是通过运行下面的测试看起来我错了。
public class Main {
public static void main(String[] args){
Obj1 one = new Obj1();
Obj1 two = new Obj1();
//is this calling hashCode() in backend???
if(one == two) {
System.out.println("same");
}
else {
System.out.println("nope");
}
//this is of course return true
if(one == one) {
System.out.println("one and one is same");
}
}
}
class Obj1 {
@Override
public int hashCode() {
System.out.println("hashCode() is called");
return 111;
}
@Override
public boolean equals(Object another) {
System.out.println("equals() is called");
return false;
}
}
根据使用== operator
的测试,看看是否调用了equals()
,而不是。{/ p>
所以我的问题是如果== operator
可以用来比较对象是否相同,那么重写e quals()
和hashCode()
方法的重点是什么? == operator
是不是已经完成了工作?
参考:
Overriding hashCode() - is this good enough?
http://mindprod.com/jgloss/hashcode.html
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)
答案 0 :(得分:5)
==运算符确定2个引用是否指向同一个对象。
所以
Object o1 = new Object();
Object o2 = o1;
o1 == o2; //true
o2 = new Object();
o1 == o2 // false
Object.equals()方法是“我如何确定对同一对象的2个引用是否相等?”
如果两个引用指向同一个对象,则
o1 == o2
o1.equals(o2)
应该是真的。
但是如果o1和o2不是同一个对象,那么它们可能在逻辑上相等。对于任何给定的类,equals取决于对象背后的语义。例如,考虑一个类,其中field1和field2由用户设置,但是field3被计算并且具有计算的随机元素。在这种情况下将equals定义为仅依赖于field1和field2而不是field3可能是有意义的。这就是为什么平等是必要的。
答案 1 :(得分:4)
==
是身份。
.equals()
是平等的。
.equals()
默认只使用==
(就像hashCode()
默认为System.identityHashCode()
但是如果有更有意义的方法来检查相等性,则可以覆盖它们。通常这样是一种“结构”平等。即:this
.equal()
的所有部分that
{{1}}的所有部分?
答案 2 :(得分:2)
如果您还没有副本;购买Joshua Bloch的Effective Java副本。
这是Java开发人员的事实参考,并且有很多关于此(以及许多其他)主题的信息。
答案 3 :(得分:2)
==
(用于对象而不是原始值)测试2个对象是否实际上是同一个对象;它会比较指针是否实际指向同一个内存位置。
.equals()
由对象本身定义。
String s1 = new String("Hello");
String s2 = new String("Hello");
boolean b1 = ( s1 == s2 ) ; // false: s1 and s2 point to different objects
boolean b2 = ( s1.equals(s2) ) ; // true: s1 and s2 both represent the same
// piece of text - "Hello"
.hashCode()
是一种优化技巧(无论如何,它的大部分用途)。标准库中的很多代码假设如果o1.equals(o2)==true
然后o1.hashCode()==o2.hashCode()
,那么o1.hashCode()!=o2.hashCode()
然后o1.equals(o2)==false
以便更快地工作
这种优化最明显的例子是HashMap类。这使得使用键真正快速检索对象,但如果hashCode和equals对关键元素不能正常工作,则会严重破坏。实际上,这是String类是不可变的原因之一:如果你能够修改一个String(并因此更改其hashCode),而String是HashMap中的键,那么你将永远无法找到它,因为你最终会在错误的地方寻找它!
其他答案推荐约书亚布洛赫Effective Java。如果你问这样的问题,那么现在是你职业生涯中购买这本书并阅读封面的最佳时机。这也将是值得重新阅读它在一两年的时间,当你已经忘记了它的一些更多的它才有意义......
答案 4 :(得分:1)
大多数已经回答了,所以这里只是另一个有启发性的例子:
String s1 = "foo";
String s2 = "foo";
System.out.println(s1 == s2); // true, because same reference (string pool)
String s3 = new String("foo");
String s4 = new String("foo");
System.out.println(s3 == s4); // false, because different reference
System.out.println(s3.equals(s4)); // true, because same value
答案 5 :(得分:0)
==
运营商 - >检查天气2参考指向同一对象与否。如果相同则返回true,否则为false。
equals( )
- >检查引用和状态对象。听到状态意味着对象数据。在这个任何一个是真的它返回true。否则是假的。但是我们必须在用户定义的对象中覆盖equals( )
并编写适当的代码。
Hashcode( )
- > Object的hashCode只表示一个随机数,JVM可以在将对象保存/添加到Hashsets,Hashtables或Hashmap时使用该随机数。
hashcode()
class TestHasChode
{
int i;
TestHasChode(int i)
{
this.i = i;
}
public static void main(String arg[])
{
//before overriding hashcode()
TestHasChode t1 = new TestHasChode(100);
TestHasChode t2 = new TestHasChode(110);
System.out.println(t1); //TestHasChode@45e41830
System.out.println(t2); //TestHasChode@1f01b29
TestHasChode t3 = new TestHasChode(100);
TestHasChode t4 = new TestHasChode(100);
System.out.println(t3); //TestHasChode@3a8721bd
System.out.println(t4); //TestHasChode@7db81d4f
/*hashCode() of Object class implemented to return hashCode based on address of an object, but based
on our requirement we can override hashCode() to generate our own numbers as hashCodes*/
//after overriding hashcode()
System.out.println(t3); //TestHasChode@64
System.out.println(t4); //TestHasChode@64
}
public int hashCode(){
return i;
}
}
-->Example of equals()method
class Student
{
String name;
int rollno;
Student(String name,int rollno)
{
this.name = name;
this.rollno = rollno;
}
public static void main(String arg[])
{
//before overrideng equals method
Student s1 = new Student ("raju", 101);
Student s2 = new Student ("giri", 102);
Student s3 = new Student ("giri", 102);
System.out.println(s1.equals(s2));//false
System.out.println(s2.equals(s3));//false
//after overriding equals method
System.out.println(s1.equals(s2));//false
System.out.println(s2.equals(s3));//true-->hear overriding equals() checks state.so it is true.
//in string variables comparisition
String s4="hello";
String s5=new String("hello");
String s6=new String("hello");
System.out.println(s4.equals(s5));//true--> because String class containg overridden equals method
System.out.println(s5.equals(s6));//true-->even though differnet object reference but String class containg overridden equals method
}
public boolean equals(Object obj){
String name1 = this.name;
int rollno1 = this.rollno;
Student s2 = (Student)obj;
String name2 = s2.name;
int rollno2 = s2.rollno;
if(name1.equals(name2) && rollno1 == rollno2){
return true;}
else{
return false;}
}
}