为什么HashMap的Hashcode为零

时间:2013-08-02 08:18:37

标签: java performance

我正在尝试使用方法一初始化:

Map<String, String> mapInter = Collections.EMPTY_MAP;
mapInter = new HashMap<String, String>();
mapInter.put("one", "one");
System.out.println(mapInter.hashCode());        

方法二:

HashMap<String, String> myMap = new HashMap<String, String>(10);
myMap.put("key", "value");
System.out.println(myMap.hashCode());

在第一种方法中,当我打印哈希码时,它的打印为零,但在第二种方法中,它打印哈希码。在初始化之后将返回hashcode。

为什么第一个案例中的HashCode打印为零而不是第二个案例?

5 个答案:

答案 0 :(得分:4)

HashCode仅在Keyvalue相同时才为0。

由于HashMap中的Entry的哈希码实现正在发生,具体如下:

public final int hashCode() 
{
  return (key==null   ? 0 : key.hashCode()) ^ (value==null ? 0 : value.hashCode());
}

它对键和值的哈希码执行^,如果两者都相同,则总是返回0.

在您的示例中,如果您更改myMap.put("key", "key"),则两个地图都将返回哈希码0。

Map<String, String> mapInter = Collections.EMPTY_MAP;
mapInter = new HashMap<String, String>();
mapInter.put("one", "one");     
System.out.println(mapInter.hashCode());

方法二:

HashMap<String, String> myMap = new HashMap<String, String>(10);
myMap.put("key", "key");
System.out.println(myMap.hashCode());

<强>输出:

0
0

答案 1 :(得分:2)

在初始化中使用Collections.EMPTY_MAP,就像你在方法一中使用的那样,没有

您将EMPTY_MAP字段分配给变量,但随后会立即覆盖它。如果您根本没有执行第一项任务,那么您的代码将是相同的,例如:

Map<String, String> mapInter;
mapInter = new HashMap<String, String>();
mapInter.put("one", "one"); 

Map<String, String> mapInter = new HashMap<String, String>();
mapInter.put("one", "one");   

变量以前具有的值与当前对象的哈希码无关。

答案 2 :(得分:0)

我建议采用方法三:

Map<String, String> map = new HashMap<>(10);
map.put("key", "value");

如果您决定不使用HashMap,那么您只需要修改一件事。

答案 3 :(得分:0)

以下代码中的第1行是多余的,因为您在第2行中覆盖了它。

Map<String, String> mapInter = Collections.EMPTY_MAP;
mapInter = new HashMap<String, String>();

上面的代码等于

Map<String, String> mapInter = null;
mapInter = new HashMap<String, String>();

这也等于

Map<String, String> mapInter = new HashMap<String, String>();

答案 4 :(得分:0)

Collections类仅包含对集合进行操作或返回集合的静态方法。 Noe为你的Collections.EMPTY_MAP。它相当于调用以下方法

/**
 * Returns the empty map (immutable).  This map is serializable.
 *
 * <p>This example illustrates the type-safe way to obtain an empty set:
 * <pre>
 *     Map&lt;String, Date&gt; s = Collections.emptyMap();
 * </pre>
 * Implementation note:  Implementations of this method need not
 * create a separate <tt>Map</tt> object for each call.   Using this
 * method is likely to have comparable cost to using the like-named
 * field.  (Unlike this method, the field does not provide type safety.)
 *
 * @see #EMPTY_MAP
 * @since 1.5
 */
@SuppressWarnings("unchecked")
public static final <K,V> Map<K,V> emptyMap() {
    return (Map<K,V>) EMPTY_MAP;
}

public static final Map EMPTY_MAP = new EmptyMap<>();

所以基本上它返回一个没有数据的Map。