==运算符和equals()之间有什么区别? (用hashcode()???)
我正在更深入地学习哈希码,并认为:
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()
而不是。
所以我的问题是如果== operator
可以用于比较对象是否相同,那么重写e quals()
和hashCode()
方法的重点是什么? 是不是== operator
已经完成了这项工作?
参考:
覆盖hashCode() – 这还不错吗?
http://mindprod.com/jgloss/hashcode.html
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)
==运算符确定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可能是有意义的。 这就是为什么平等是必要的。
==
是身份。
.equals()
是平等的。
.equals()
默认只使用==
(就像hashCode()
默认为System.identityHashCode()
但是如果有更有意义的方法来检查相等性,你可以覆盖它们。通常这是一种“结构”相等。即:所有这些部分都是.equal()
的所有部分?
如果你还没有副本; 购买Joshua Bloch的Effective Java副本。
这是Java开发人员事实上的参考,并且有很多关于这个(以及许多其他)主题的信息。
==
(用于对象而不是原始值)测试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中的键,那么你永远无法找到它,因为你最终会在错误的地方寻找它!
其他答案推荐Joshua Bloch的Effective Java 。 如果你问这样的问题,那么现在是你职业生涯中购买这本书并阅读封面的最佳时机。 它也值得在一两年内重新阅读,当你忘记了一些时,它会更有意义……
大多数已经回答了,所以这里只是另一个有启发性的例子:
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
==
运算符 – >检查天气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;} } }
- 为什么更改用作HashMap中的键的对象的哈希码会使查找返回null?
- 如何实现与hibernate相等而不会失去对称属性的风险?
- ArrayList – 添加“相同”对象(same => equals,hashCode),Threads
- 一致的Equals()结果,但不一致的TreeMap.containsKey()结果
- Apache Commons Lang3 Hashcode,Equals和ToString包括Enums
- Joshua Bloch在有效的java中建议如何在Java中使用缓存哈希码?
- 将对象的哈希码定义为所有类变量哈希码的总和,乘法等是不正确的?
- 如何在Objective-C中获得Java String.hashCode()的相同结果?
- 使用HashMap计算实例