HashMap中出现重复值

4

我有一个问题,创建了一个HashMap,并使用StringBuilder作为键插入了两个值。

现在,当尝试使用StringBuilder对象检索数据时,它可以正常工作,但在其他情况下,它无法返回任何值。在下面的代码中,我列出了三种情况:

`

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
}

} `

6个回答

2

在方法receiveMap

System.out.println("Expected value a, not coming  => " + map.get(sb)); // why null ?

由于您在方法中创建了一个新的 StringBuilder sb,该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不允许重复,但是由于StringBuilder没有重写equals和hashcode方法,所以它仍然会打印[sb, sb]


1

简单来说,一个 StringBuilder 实例不等于另一个实例(因此它们将获得不同的哈希码,并被视为独立实体)。仅仅因为两个 StringBuilder(或任何对象)具有相同的值,并不意味着它们是相同的。


1
String 不同,StringBuilder 没有覆盖 equalshashCode,因此它使用了 Object 类的默认实现。因此,即使它们包含相同的字符,sb.equals(sb1) 也是 false。
我建议您将 String 而不是 StringBuilder 用作 Map 的键。

0

您已经创建了不同的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

这里还创建了新的对象sb1sb,它们与之前创建的对象不相等,尽管内容相同,但引用不同。

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.


0
使用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

0

您正在传递不在Map中的对象,因此返回null。每次传递正确的对象时,您都会得到值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接