HashMap 中的重复值
Duplicate Value in HashMap
我遇到了大麻烦,创建了一个 hashMap 并使用相同的键插入了两个值
StringBuilder 作为地图的键。
现在,虽然尝试使用 StringBuilder 对象检索数据工作正常,但在其他情况下它无法 return 任何值。我在下面给出的代码中列出了三种情况,
`
class MainClass {
public static void main(String[] args) {
MainClass m = new MainClass();
StringBuilder sb = new StringBuilder("sb");
StringBuilder sb1 = new StringBuilder("sb");
Map<StringBuilder, String> map = new HashMap<StringBuilder, String>();
map.put(sb, "a");
map.put(sb1, "b");
System.out.println("----Inside Main method---- mapValue"+map);
System.out.println("Expected value a, coming also => " + map.get(sb)); //a
System.out.println("Expected value b, coming also => " + map.get(sb1)); //b
System.out.println("Expected value a, not coming => " + map.get("sb")); // why null ?
m.receiveMap(map, sb, sb1);
}
public void receiveMap(Map<StringBuilder, String> map, StringBuilder refSb,StringBuilder refSb1) {
StringBuilder sb = new StringBuilder("sb");
StringBuilder sb1 = new StringBuilder("sb");
System.out.println("----Inside receiveMap method mapValue"+map);
System.out.println("Expected value a, not coming => " + map.get(sb)); // why null ?
System.out.println("Expected value b, not coming => " + map.get(sb1)); // why null ?
System.out.println("Expected value a, coming also => " + map.get(refSb)); // o/p - a
System.out.println("Expected value b, coming also => " + map.get(refSb1)); // o/p -b
}
}
`
简单,一个 StringBuilder
实例不等于另一个实例(因此它们将获得不同的哈希码,并作为单独的实体处理)。仅仅因为 2 StringBuilder
(或任何对象)具有相同的值,并不意味着它们相同。
与 String
不同,StringBuilder
不会覆盖 equals
和 hashCode
,因此使用 Object
class 的默认实现].因此 sb.equals(sb1)
是错误的,即使它们包含相同的字符。
我建议您使用 String
而不是 StringBuilder
作为地图的键。
您创建了 StringBuilder
的不同实例,它们并不相同。
你自己已经测试了几乎所有的场景,混淆应该已经清楚了。
StringBuilder
不会覆盖 hashCode()
和 equals()
方法,HashMap
需要这些方法才能正常工作。
System.out.println("Expected value a, not coming => " +
map.get("sb")); // why
新StringBuilder object
已创建并通过
> StringBuilder sb = new StringBuilder("sb");
> StringBuilder sb1 = new StringBuilder("sb");
> System.out.println("----Inside receiveMap method mapValue" + map);
> System.out.println("Expected value a, not coming => " + map.get(sb)); // why
> System.out.println("Expected value b, not coming => " + map.get(sb1)); // why
此处还创建了新对象 sb1
和 sb
,它们与之前创建的对象不同,尽管内容相同,但引用不同。
Also try changing Map to
Map<String, String> map = new HashMap<String, String>();
and use .toString()
method, you will observe different behaviour,
because String
class overrides hashCode()
and equals()
method.
您正在传递不在 Map 中的对象,因此 returns null.Every 当您传递正确的对象时,您将获得价值。
使用 StringBuilder 它永远不会工作,因为一个实例不等于另一个 StringBuilder 实例
将您的代码更正为这样的内容
Map<String, String> map = new HashMap<String, String>();
map.put(sb.toString(), "a");
map.put(sb1.toString(), "b");
但是因为这是地图表示,如果 sb.toString() 和 sb1.toString() 像您的示例中那样相等,则该值将被覆盖
所以对您的代码进行更正后的输出是
----Inside Main method---- mapValue{sb=b}
Expected value a, coming also => b
Expected value b, coming also => b
Expected value a, not coming => b
----Inside receiveMap method mapValue{sb=b}
Expected value a, not coming => b
Expected value b, not coming => b
Expected value a, coming also => b
Expected value b, coming also => b
在方法中 receiveMap
System.out.println("Expected value a, not coming => " + map.get(sb)); // why null ?
因为你正在创建新的 StringBuilder
sb 在具有不同的方法
哈希码与 StringBuilder sb PSVM.
比较
StringBuilder 不会覆盖 equals 和 hashCode
StringBuilder sb = new StringBuilder("sb");
StringBuilder sb1 = new StringBuilder("sb");
Set s = new HashSet();
s.add(sb);
s.add(sb1);
System.out.println(s);
Set 不允许重复,但它仍然打印 [sb, sb]
,因为 StringBuilder 不会覆盖 equals 和 hashcode 方法。
我遇到了大麻烦,创建了一个 hashMap 并使用相同的键插入了两个值 StringBuilder 作为地图的键。 现在,虽然尝试使用 StringBuilder 对象检索数据工作正常,但在其他情况下它无法 return 任何值。我在下面给出的代码中列出了三种情况,
`
class MainClass {
public static void main(String[] args) {
MainClass m = new MainClass();
StringBuilder sb = new StringBuilder("sb");
StringBuilder sb1 = new StringBuilder("sb");
Map<StringBuilder, String> map = new HashMap<StringBuilder, String>();
map.put(sb, "a");
map.put(sb1, "b");
System.out.println("----Inside Main method---- mapValue"+map);
System.out.println("Expected value a, coming also => " + map.get(sb)); //a
System.out.println("Expected value b, coming also => " + map.get(sb1)); //b
System.out.println("Expected value a, not coming => " + map.get("sb")); // why null ?
m.receiveMap(map, sb, sb1);
}
public void receiveMap(Map<StringBuilder, String> map, StringBuilder refSb,StringBuilder refSb1) {
StringBuilder sb = new StringBuilder("sb");
StringBuilder sb1 = new StringBuilder("sb");
System.out.println("----Inside receiveMap method mapValue"+map);
System.out.println("Expected value a, not coming => " + map.get(sb)); // why null ?
System.out.println("Expected value b, not coming => " + map.get(sb1)); // why null ?
System.out.println("Expected value a, coming also => " + map.get(refSb)); // o/p - a
System.out.println("Expected value b, coming also => " + map.get(refSb1)); // o/p -b
}
} `
简单,一个 StringBuilder
实例不等于另一个实例(因此它们将获得不同的哈希码,并作为单独的实体处理)。仅仅因为 2 StringBuilder
(或任何对象)具有相同的值,并不意味着它们相同。
与 String
不同,StringBuilder
不会覆盖 equals
和 hashCode
,因此使用 Object
class 的默认实现].因此 sb.equals(sb1)
是错误的,即使它们包含相同的字符。
我建议您使用 String
而不是 StringBuilder
作为地图的键。
您创建了 StringBuilder
的不同实例,它们并不相同。
你自己已经测试了几乎所有的场景,混淆应该已经清楚了。
StringBuilder
不会覆盖 hashCode()
和 equals()
方法,HashMap
需要这些方法才能正常工作。
System.out.println("Expected value a, not coming => " + map.get("sb")); // why
新StringBuilder object
已创建并通过
> StringBuilder sb = new StringBuilder("sb");
> StringBuilder sb1 = new StringBuilder("sb");
> System.out.println("----Inside receiveMap method mapValue" + map);
> System.out.println("Expected value a, not coming => " + map.get(sb)); // why
> System.out.println("Expected value b, not coming => " + map.get(sb1)); // why
此处还创建了新对象 sb1
和 sb
,它们与之前创建的对象不同,尽管内容相同,但引用不同。
Also try changing Map to
Map<String, String> map = new HashMap<String, String>();
and use
.toString()
method, you will observe different behaviour, becauseString
class overrideshashCode()
andequals()
method.
您正在传递不在 Map 中的对象,因此 returns null.Every 当您传递正确的对象时,您将获得价值。
使用 StringBuilder 它永远不会工作,因为一个实例不等于另一个 StringBuilder 实例
将您的代码更正为这样的内容
Map<String, String> map = new HashMap<String, String>();
map.put(sb.toString(), "a");
map.put(sb1.toString(), "b");
但是因为这是地图表示,如果 sb.toString() 和 sb1.toString() 像您的示例中那样相等,则该值将被覆盖
所以对您的代码进行更正后的输出是
----Inside Main method---- mapValue{sb=b}
Expected value a, coming also => b
Expected value b, coming also => b
Expected value a, not coming => b
----Inside receiveMap method mapValue{sb=b}
Expected value a, not coming => b
Expected value b, not coming => b
Expected value a, coming also => b
Expected value b, coming also => b
在方法中 receiveMap
System.out.println("Expected value a, not coming => " + map.get(sb)); // why null ?
因为你正在创建新的 StringBuilder
sb 在具有不同的方法
哈希码与 StringBuilder sb PSVM.
StringBuilder 不会覆盖 equals 和 hashCode
StringBuilder sb = new StringBuilder("sb");
StringBuilder sb1 = new StringBuilder("sb");
Set s = new HashSet();
s.add(sb);
s.add(sb1);
System.out.println(s);
Set 不允许重复,但它仍然打印 [sb, sb]
,因为 StringBuilder 不会覆盖 equals 和 hashcode 方法。