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
?我已经阅读了putIfAbsent
的语义,应该保证它能够正常工作。 (注意:这是从大型并发程序中提炼出来的......正如您所看到的,它现在是单线程的。)
答案 0 :(得分:5)
putIfAbsent()不使用ConcurrentHashMap
"hi".getBytes()
不是常量数组,因此您在那里生成两个不同的对象。如果您执行了以下操作,则会看到1
。
byte[] bytes = "hi".getBytes();
System.out.println(dps.putIfAbsent(bytes, 1));
System.out.println(dps.putIfAbsent(bytes, 1));
hashCode()
数组上的equals(...)
和byte[]
方法来自Object
,它只查看对象的引用,而不是其内容
每当您在Map
中存储某些内容时,您需要确保它覆盖hashCode()
和equals(...)
方法,除非您只想比较引用。这是一个Java FAQ。请参阅以下文档:Java theory and practice: Hashing it out。
正如@Mauren在评论中提到的那样,要使用byte[]
的内容,你将不得不写一个包装byte[]
的小班并提供正确的{ {1}}和hashCode()
方法。或者@CostiCiudatu提及,您可以使用equals(...)
并使用SortedMap
作为Comparator
查看数组内容。
顺便说一句,如果byte[]
根据您的字符集等返回使用String.getBytes()
类编码的new byte[]
。