![](/img/trans.png)
[英]Expected NullPointerException with ConcurrentHashMap doesn't show up
[英]ConcurrentHashMap doesn't work as expected when use byte array as key in Xamarin
这是我在Xamarin Android中使用的代码块。
Java.Util.Concurrent.ConcurrentHashMap map = new Java.Util.Concurrent.ConcurrentHashMap();
var key = new byte[] { 1, 2, 3 };
var data = new byte[] { 1, 2, 3, 4, 5 };
map.Put(key, data);
var val = map.Get(key); // null, WHY?
IEnumeration keys = map.Keys();
while (keys.HasMoreElements)
{
var k = keys.NextElement();
var val2 = map.Get(k); // NOT null, val2 is byte array of {1,2,3,4,5}
}
我期望val
是字节数组(数据),但是val
为null,而val2
不为null。
但是此Java代码效果很好。
java.util.concurrent.ConcurrentHashMap map = new java.util.concurrent.ConcurrentHashMap();
byte[] key = {1, 2, 3};
byte[] data = {1, 2, 3, 4, 5};
map.put(key, data);
Object o = map.get(key); // byte array of {1,2,3,4,5}
是什么原因?
使用字节数组作为Java映射的键确实是个坏主意,原因有几个:数组是可变的,数组没有引用相等性。 这两件事都破坏了Map的一般合同。 我建议您为地图使用其他密钥。 有关更多信息,请参见此问题及其答案,包括将字节数组转换为可用的映射键的一些可能方法。
只要您只希望键的引用相等-数组就不会以您可能想要的方式实现“ value equality
”,但是List会实现。 例如:
byte[] key = new byte[] { 1, 2, 3 };
byte[] data = new byte[] { 1, 2, 3 };
System.out.println(key.equals(data));
System.out.println(key.hashCode());
System.out.println(data.hashCode());
这将给出输出:
false
1829164700
2018699554
示例2 ::
int[] key = new int[] { 1, 2, 3 };
int[] data = new int[] { 1, 2, 3 };
List<Integer> list1 = Arrays.asList(1, 2);
List<Integer> list2 = Arrays.asList(1, 2);
System.out.println("Comparison between LIST ::" + list1.equals(list2));
System.out.println("Comparison between arrays ::" + key.equals(data));
System.out.println(key.hashCode());
System.out.println(data.hashCode());
输出为::
Comparison between LIST ::true
Comparison between arrays ::false
1829164700
2018699554
问题在于,byte []将对象标识用于equals
和hashCode
,因此在HashMap中将不匹配。
您可以使用给定的选项:
List<Byte>
(在内存中可能会很昂贵)。 hashCode
并equals
使用字节数组的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.