什么问题/陷阱,必须重写时,必须考虑equals和hashCode?
请澄清我对Hashset的疑问.考虑以下代码,
class Person
{
String name;
Person(String n)
{
name=n;
}
public String getName()
{
return name;
}
@Override
public boolean equals(Object arg0) {
System.out.println("in equals");
Person obj=(Person)arg0;
System.out.println("1st "+getName());
System.out.println("2nd "+obj.getName());
if(this.getName().equals(obj.getName()))
{
return true;
}
return false;
}
@Override
public int hashCode() {
System.out.println("in hash code");
System.out.println(" value is "+Integer.valueOf(name.charAt(0)));
return Integer.valueOf(name.charAt(0));
}
}
Run Code Online (Sandbox Code Playgroud)
在主要我有以下代码
Person obj1=new Person("bcd");
Person obj2=new Person("cde");
Person obj3=new Person("abc");
Person obj4=new Person("abc");
Run Code Online (Sandbox Code Playgroud)
现在,如果我将这些对象添加到hashset
Set<Person> sset=new HashSet<Person>();
sset.add(obj1);
sset.add(obj4);
sset.add(obj2);
sset.add(obj3);
Run Code Online (Sandbox Code Playgroud)
我得到了这个输出
in hash …Run Code Online (Sandbox Code Playgroud) 这是我的代码:
public class testGui {
public static void main(String[] arg){
class TESTS{
String t;
public TESTS(String t){
this.t = t;
}
@Override
public boolean equals(Object x){
System.out.println("My method is called...");
if(x instanceof TESTS){
TESTS zzz = (TESTS) x;
return zzz.t.compareTo(t)==0;
}
else return false;
}
}
HashSet<TESTS> allItems = new HashSet<TESTS>();
allItems.add(new TESTS("a"));
allItems.add(new TESTS("a"));
System.out.println(allItems.contains(new TESTS("a")));
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么hashset包含的方法不是调用我们的规范中提到的equals方法:
更正式地,如果此set不包含元素e,则将指定的元素o添加到此set中(o == null?e == null:o.equals(e))
我的代码返回false而不是进入我的equals方法.
非常感谢您的回答!
该HashSet的类有一个附加(对象o)方法,这是不从另一个类继承的.该方法的Javadoc说明如下:
如果指定的元素尚不存在,则将其添加到此集合中.更正式地,将指定的元素
e这套如果此集合不包含任何元素e2,使得(e==null ? e2==null : e.equals(e2)).如果此set已包含该元素,则调用将保持set不变并返回false.
换句话说,如果两个对象相等,则不会添加第二个对象,并且HashSet将保持不变.然而,我发现,这是不正确的,如果对象e和e2,有不同的哈希码尽管e.equals(e2).这是一个简单的例子:
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
public class BadHashCodeClass {
/**
* A hashcode that will randomly return an integer, so it is unlikely to be the same
*/
@Override
public int hashCode(){
return new Random().nextInt();
}
/**
* An equal method that will always return true
*/
@Override
public boolean equals(Object o){
return true; …Run Code Online (Sandbox Code Playgroud) 如果指定的元素尚不存在,则将其添加到此集合中.更正式地,如果此集合不包含元素e2(e == null?e2 == null:e.equals(e2)),则将指定元素e添加到此集合.如果此set已包含该元素,则调用将保持set不变并返回false.
由于我的代码将返回false e.equals(e2),我希望它允许我添加两次相同的实例.但该集只包含我的实例一次.有人可以解释原因吗?
package com.sandbox;
import java.util.HashSet;
import java.util.Set;
public class Sandbox {
public static void main(String[] args) {
Set<A> as = new HashSet<A>();
A oneInstance = new A();
System.out.println(oneInstance.equals(oneInstance)); //this prints false
as.add(oneInstance);
as.add(oneInstance);
System.out.println(as.size()); //this prints 1, I'd expect it to print 2 since the System.out printed false
}
private static class A {
private Integer key;
@Override
public boolean equals(Object o) {
if (!(o instanceof A)) {
return false; …Run Code Online (Sandbox Code Playgroud) 这是我测试HashSet的示例代码.我希望结果是[3K,1K]但这个代码导致[1K,3K,3K]
你能让我知道为什么代码不能调用等于?
import java.util.HashSet;
class SutdaCard{
private int num;
private boolean isKwang;
SutdaCard(){
this(1,true);
}
SutdaCard(int num, boolean isKwang){
this.num = num;
this.isKwang = isKwang;
}
public String toString(){
return num+(isKwang ? "K":"");
}
public boolean equals(Object obj){
String compareValue = obj.toString();
String thisValue = toString();
System.out.println("equals");
return thisValue.equals(compareValue);
}
public int hashcode(){
return toString().hashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
class exercise11_11 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<SutdaCard> set = new …Run Code Online (Sandbox Code Playgroud)