这是我的代码:
import java.util.HashMap;
class MyString
{
String string;
MyString(String string)
{
this.string = new String(string);
}
}
public class test
{
public void test3()
{
HashMap<MyString, Byte> byteHashMap = new HashMap<MyString, Byte>();
char c = 'A';
byte b = (byte)c;
String string = new String("The Letter A");
MyString myString = new MyString(string);
byteHashMap.put(myString, b);
if (byteHashMap.containsKey(myString))
//if (byteHashMap.containsKey(new MyString(string)))
{
System.out.println("true");
}
else
{
System.out.println("false");
}
}
public static void main(String[] args)
{
test testObject = new test();
testObject.test3();
}
}
我想知道为什么代码返回true。但是,当我切换if语句(参见注释行)时,它返回false。
我认为它与覆盖MyString类中的equals方法有关,但我不确定如何处理它。
问候。
答案 0 :(得分:3)
是的,覆盖hashCode
和equals
。
现在,您将比较字符串与MyString
对象的内存引用(标准实现)。
例如
@Override
public bool equals(Object args0) {
if(args0 == this) { return true; }
if(!(args0 instanceof MyString)) { return false; }
MyString obj = (MyString) args0;
return obj.getString().equals(this.string); // Create getter
}
@Override
public int hashCode(){
return this.string.hashCode() * 37;
}
答案 1 :(得分:3)
你的信念是正确的。地图结构依赖于.equals
来确定地图中是否已存在密钥。默认情况下,对象类型具有实例相等性(当且仅当a.equals(b)
和a
指向同一对象时,意味着b
为真。)
在您的情况下,如果MyString
字段相等,您可能希望两个string
实例相等。在这种情况下,您可以使用以下内容覆盖equals
:
@Override
public boolean equals(Object other) {
if (other == null) { return false; }
if (!(other instanceof MyString)) { return false; }
MyString m = (MyString)other;
return this.string.equals(m.string);
}
这样,两个if语句中的任何一个都将返回true。
您还应该覆盖hashCode
。如果您使用Eclipse,它可以通过Source
菜单轻松地为您生成这两种方法。
答案 2 :(得分:1)
您需要实现hashCode和equals。 HashMaps基于hashCode将对象放入存储桶中。不同的对象可以具有相同的hashCode,但规则是两个相等的对象必须具有相同的hashCode。一旦HashMap找到具有相同hashCode的所有条目,它就会使用equals方法检查相等性。
默认实现检查对象实例是否相等 - 也就是说,两个对象是同一个实例。在您的情况下,您正在检查两个不同的实例。
重写equals和hashCode方法,以传递hashCode()和equals()为私有String成员变量返回的值,假设这是确定类的两个实例是否相等的全部内容。