0
public static void main(String args[]) throws Exception {
    ConcurrentHashMap<byte[], Integer> dps =
         new ConcurrentHashMap<byte[], Integer>();

    System.out.println(dps.putIfAbsent("hi".getBytes(), 1));
    System.out.println(dps.putIfAbsent("hi".getBytes(), 1));
}

印刷

null
null

为什么它不在1第二行打印 a ?我已经阅读了语义,putIfAbsent应该保证它可以工作。(注意:这是从一个大型并发程序中提炼出来的……如您所见,它现在是单线程的。)

4

1 回答 1

5

putIfAbsent() 不适用于 ConcurrentHashMap

"hi".getBytes()不是一个常量数组,所以你在那里生成两个不同的对象。如果您执行以下操作,您将看到您的1.

byte[] bytes = "hi".getBytes();
System.out.println(dps.putIfAbsent(bytes, 1));
System.out.println(dps.putIfAbsent(bytes, 1));

array 上的hashCode()andequals(...)方法是 from它只查看对象的引用,而不是其内容。byte[]Object

每当您将某些内容存储在 a 中Map时,您都需要确保它覆盖hashCode()equals(...)方法,除非您只想比较引用。这是一个 Java 常见问题解答。请参阅这些文档:Java 理论与实践:Hashing it out

正如@Mauren 在评论中提到的那样,要使用您的内容byte[]您将不得不编写一个小类来包装byte[]并提供适当的hashCode()equals(...)方法。或者正如@CostiCiudatu 提到的那样,您可以使用 aSortedMap并使用 a Comparatorfor byte[]which 查看数组的内容。

顺便说一句,如果根据您的字符集等String.getBytes()返回一个new byte[]用类编码的值。StringCoding.StringEncoder

于 2013-10-01T19:57:39.410 回答