以下是我在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
为空,而val2
不为空。
但是这个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}
是什么原因?
答案 0 :(得分:1)
使用字节数组作为Java映射的关键是一个非常糟糕的主意,原因有几个:数组是可变的,数组不具有引用相等性。这两件事都破坏了Map的总契约。我建议你为地图使用不同的键。有关更多信息,请参阅this question及其答案,包括将字节数组转换为可用的映射键的一些可能方法。
答案 1 :(得分:1)
只要你只希望你的密钥引用相等 - 数组就不能实现" 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
以使用字节数组的内容。