Java-HashMap.containsKey为对象返回不正确的值

Java-HashMap.containsKey为对象返回不正确的值,java,object,hashmap,equals,containskey,Java,Object,Hashmap,Equals,Containskey,这是我的密码: 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 HashMa

这是我的密码:

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();
  }
}
import java.util.HashMap;
类MyString
{
字符串字符串;
MyString(字符串)
{
this.string=新字符串(string);
}
}
公开课考试
{
公共无效测试3()
{
HashMap byteHashMap=新HashMap();
字符c='A';
字节b=(字节)c;
字符串=新字符串(“字母A”);
MyString MyString=新MyString(字符串);
byteHashMap.put(myString,b);
if(byteHashMap.containsKey(myString))
//if(byteHashMap.containsKey(新MyString(string)))
{
System.out.println(“真”);
}
其他的
{
System.out.println(“假”);
}
}
公共静态void main(字符串[]args)
{
test testObject=new test();
testObject.test3();
}
}
我想知道为什么代码返回true。但是,当我切换if语句时(参见注释行),它返回false

我相信这与重写MyString类中的equals方法有关,但我不确定如何实现这一点


注意。

是,覆盖
hashCode
等于
。
现在,您将比较字符串与
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;
}

是,覆盖
hashCode
等于
。 现在,您将比较字符串与
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;
}

你的信念是正确的。映射结构依赖于
.equals
来确定映射中是否已经存在密钥。默认情况下,对象类型具有实例相等性(即当且仅当
a
b
指向同一对象时,
a.equals(b)
为真)

在您的例子中,如果
字符串
字段相等,您可能希望两个
MyString
实例相等。在这种情况下,您将使用以下内容覆盖
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
菜单非常轻松地为您生成这两种方法。

您的想法是正确的。映射结构依赖于
.equals
来确定映射中是否已经存在密钥。默认情况下,对象类型具有实例相等性(即当且仅当
a
b
指向同一对象时,
a.equals(b)
为真)

在您的例子中,如果
字符串
字段相等,您可能希望两个
MyString
实例相等。在这种情况下,您将使用以下内容覆盖
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
菜单非常轻松地为您生成这两个方法。

您需要实现hashCode和equals。HashMaps根据hashCode将对象放入存储桶中。不同的对象可以具有相同的哈希代码,但规则是两个相等的对象必须具有相同的哈希代码。一旦HashMap找到具有相同hashCode的所有条目,它就会使用equals方法检查是否相等

默认实现检查对象实例是否相等,即两个对象是否为同一实例。在您的例子中,您正在检查两个不同的实例


重写equals和hashCode方法,以传递由私有字符串成员变量的hashCode()和equals()返回的值,假设这就是确定类的两个实例是否相等的全部内容

您需要实现hashCode和equals。HashMaps根据hashCode将对象放入存储桶中。不同的对象可以具有相同的哈希代码,但规则是两个相等的对象必须具有相同的哈希代码。一旦HashMap找到具有相同hashCode的所有条目,它就会使用equals方法检查是否相等

默认实现检查对象实例是否相等,即两个对象是否为同一实例。在您的例子中,您正在检查两个不同的实例


重写equals和hashCode方法,以传递由私有字符串成员变量的hashCode()和equals()返回的值,假设这就是确定类的两个实例是否相等的全部内容

eclipse的评论太完美了!Source>生成hashCode()和equals()。感谢you@DannyRancher很高兴这有帮助。Equals和hashCode很重要,像Eclipse这样的工具使正确操作变得更容易,尽管不一定理解为什么需要它们。Eclipse的注释非常完美!Source>生成hashCode()和equals()。感谢you@DannyRancher很高兴这有帮助。Equals和hashCode很重要,像Eclipse这样的工具使正确操作变得更容易,尽管不一定理解为什么需要它们。我将这两个方法都添加到了我的String类中,但在执行containsKey方法时,Equals方法甚至没有被调用。有什么想法吗?我想这是因为哈希代码不一样,即使字符串的值看起来完全一样,我已经修剪了它们。所以我不知道为什么它们返回不同的散列码。我将这两个方法都添加到我的String类中,但在执行containsKey方法时,甚至没有调用equals方法。有什么想法吗?我想这是因为哈希代码不一样,即使字符串的值看起来完全一样,我已经修剪了它们。所以我不知道为什么它们返回不同的散列码。