Java putIfAbsent()不使用ConcurrentHashMap

Java putIfAbsent()不使用ConcurrentHashMap,java,concurrency,hashmap,concurrenthashmap,Java,Concurrency,Hashmap,Concurrenthashmap,为什么它不在第二行打印1?我已经阅读了putIfAbsent的语义,应该保证它能正常工作。(注意:这是从一个大型并发程序中提炼出来的……正如您所看到的,它现在是单线程的。) putIfAbsent()不使用ConcurrentHashMap “hi”.getBytes()不是一个常量数组,因此在那里生成两个不同的对象。如果您执行了以下操作,您将看到您的1 null null byte[]数组上的hashCode()和equals(…)方法来自Object,它只查看对象的引用,而不查看对象的内容

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

putIfAbsent()不使用ConcurrentHashMap

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

null
null
byte[]
数组上的
hashCode()
equals(…)
方法来自
Object
,它只查看对象的引用,而不查看对象的内容


每当您在
Map
中存储某个内容时,您需要确保它覆盖
hashCode()
equals(…)
方法,除非您只想比较引用。这是一个Java常见问题解答。请参阅以下文档:

正如@Mauren在评论中提到的,要使用
byte[]
的内容,您必须编写一个小类,它包装
byte[]
并提供适当的
hashCode()
equals(…)
方法。或者正如@CostiCiudatu所提到的,您可以使用
SortedMap
比较器
来查看数组的内容

另一方面,if
String.getBytes()
返回一个
新字节[]
根据您的字符集使用
StringCoding.StringEncoder
类进行编码,等等

putIfAbsent()不使用ConcurrentHashMap

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

null
null
byte[]
数组上的
hashCode()
equals(…)
方法来自
Object
,它只查看对象的引用,而不查看对象的内容


每当您在
Map
中存储某个内容时,您需要确保它覆盖
hashCode()
equals(…)
方法,除非您只想比较引用。这是一个Java常见问题解答。请参阅以下文档:

正如@Mauren在评论中提到的,要使用
byte[]
的内容,您必须编写一个小类,它包装
byte[]
并提供适当的
hashCode()
equals(…)
方法。或者正如@CostiCiudatu所提到的,您可以使用
SortedMap
比较器
来查看数组的内容


另一方面,如果
String.getBytes()
返回一个
新字节[]
,该字节是根据您的字符集使用
StringCoding.StringEncoder
类编码的。

刚刚注意到,如果我将
字节[]
更改为
String
(当然删除
getBytes()
),那么我就得到了预期的行为。但是我的
String
s是不同的对象,因此根据您的逻辑,它不应该工作。或者我不明白?好的,根据您的新编辑,我明白:
String
比较内容,但是
byte[]
比较引用。非常不直观。似乎使用
byte[]
作为映射键通常是个坏主意,因此@Fixee
String
已覆盖
equals()
hashCode()
方法,这就是为什么它可以正确地与
String
一起工作。每当您在
Map
中存储某个内容时,您需要确保它覆盖equals/hashCode,除非您只想比较references@Fixee。Java常见问题解答:或者您可以使用
SortedMap
(例如
TreeMap
)和
比较器
作为字节数组。这种方法在HBase中使用,它适用于为每个字节数组创建包装器对象的任何时候,因为这样做的成本太高。请注意,如果我将
byte[]
更改为
String
(当然,删除
getBytes()
),那么我就会得到预期的行为。但是我的
String
s是不同的对象,因此根据您的逻辑,它不应该工作。或者我不明白?好的,根据您的新编辑,我明白:
String
比较内容,但是
byte[]
比较引用。非常不直观。似乎使用
byte[]
作为映射键通常是个坏主意,因此@Fixee
String
已覆盖
equals()
hashCode()
方法,这就是为什么它可以正确地与
String
一起工作。每当您在
Map
中存储某个内容时,您需要确保它覆盖equals/hashCode,除非您只想比较references@Fixee。Java常见问题解答:或者您可以使用
SortedMap
(例如
TreeMap
)和
比较器
作为字节数组。这种方法在HBase中使用,只要为每个字节数组创建包装器对象的成本太高,它就非常适合。
byte[] bytes = "hi".getBytes();
System.out.println(dps.putIfAbsent(bytes, 1));
System.out.println(dps.putIfAbsent(bytes, 1));