使用一个字节数组作为Map键
你看到使用一个字节数组作为Map键有任何问题吗? 我也可以通过new String(byte[])来实现new String(byte[])和hash,但是使用byte[]会更直接。 
 问题是byte[]使用equals和hashCode对象标识,所以 
 byte[] b1 = {1, 2, 3} byte[] b2 = {1, 2, 3} 
 在HashMap不匹配。 我看到三个选项: 
-  包装在一个String,但是你必须小心编码问题(你需要确保字节 – >string – >字节给你相同的字节)。
-  使用List<Byte>(在内存中可能是昂贵的)。
-  做你自己的包装类,写hashCode,equals使用字节数组的内容。
没关系,只要你的键只需要引用相等就可以了 – 数组不会以你想要的方式实现“值相等”。 例如:
 byte[] array1 = new byte[1]; byte[] array2 = new byte[1]; System.out.println(array1.equals(array2)); System.out.println(array1.hashCode()); System.out.println(array2.hashCode()); 
打印如下:
 false 1671711 11394033 
(实际的数字是不相关的,它们不同的事实很重要。)
 假设你真的想要平等,我build议你创build自己的包装,其中包含一个byte[] ,并适当地实现相等和哈希代码生成: 
 public final class ByteArrayWrapper { private final byte[] data; public ByteArrayWrapper(byte[] data) { if (data == null) { throw new NullPointerException(); } this.data = data; } @Override public boolean equals(Object other) { if (!(other instanceof ByteArrayWrapper)) { return false; } return Arrays.equals(data, ((ByteArrayWrapper)other).data); } @Override public int hashCode() { return Arrays.hashCode(data); } } 
 请注意,如果在使用ByteArrayWrapper后将字节数组中的值更改为HashMap (etc)中的键,则在再次查找关键字时会遇到问题…您可以在ByteArrayWrapper构造函数中获取数据的副本如果你想的话,但是如果你知道你不会改变字节数组的内容,显然这将浪费性能。 
 编辑:正如在评论中提到的,你也可以使用ByteBuffer这个(特别是,它的ByteBuffer#wrap(byte[])方法)。 考虑到ByteBuffer具备的所有额外function,但是这是一个选项,我不知道它是否正确。 
我们可以使用ByteBuffer(这基本上是比较器的byte []包装器)
 HashMap<ByteBuffer, byte[]> kvs = new HashMap<ByteBuffer, byte[]>(); byte[] k1 = new byte[]{1,2 ,3}; byte[] k2 = new byte[]{1,2 ,3}; byte[] val = new byte[]{12,23,43,4}; kvs.put(ByteBuffer.wrap(k1), val); System.out.println(kvs.containsKey(ByteBuffer.wrap(k2))); 
将打印
 true 
 你可以使用java.math.BigInteger 。 它有一个BigInteger(byte[] val)构造函数。 这是一个引用types,所以可以用作散列表的键。  .equals()和.hashCode()定义为相应的整数,这意味着BigInteger与byte []数组具有一致的equals语义。 
我很惊讶,答案并没有指出最简单的select。
是的,使用HashMap是不可能的,但是没有人会阻止你使用SortedMap作为替代。 唯一的事情就是写一个需要比较数组的比较器。 它不像HashMap那么高性能,但是如果你想要一个简单的select,那么你可以去(如果你想隐藏实现,你可以用MapreplaceSortedMap):
  private SortedMap<int[], String> testMap = new TreeMap<>(new ArrayComparator()); private class ArrayComparator implements Comparator<int[]> { @Override public int compare(int[] o1, int[] o2) { int result = 0; int maxLength = Math.max(o1.length, o2.length); for (int index = 0; index < maxLength; index++) { int o1Value = index < o1.length ? o1[index] : 0; int o2Value = index < o2.length ? o2[index] : 0; int cmp = Integer.compare(o1Value, o2Value); if (cmp != 0) { result = cmp; break; } } return result; } } 
这个实现可以针对其他数组进行调整,唯一需要注意的是相等的数组(等于等于成员的长度)必须返回0,并且您有一个确定的顺序
 我相信Java中的数组并不一定直观地实现hashCode()和equals(Object)方法。 也就是说,两个相同的字节数组将不一定共享相同的哈希码,并且它们不一定要求相等。 没有这两个特性,你的HashMap就会出乎意料的performance。 
 因此,我build议不要在HashMap 中使用byte[]作为键。 
你应该使用创build一个类似的ByteArrKey和重载hashcode和等同的方法,记住它们之间的契约。
这会给你更大的灵活性,因为你可以跳过附加在字节数组末尾的0个条目,特别是如果只复制另一个字节缓冲区的一部分。
这样你将决定两个对象应该如何相等。
我看到了问题,因为你应该使用Arrays.equals和Array.hashCode来代替默认的数组实现
Arrays.toString(字节)
您还可以使用Base32或Base64将字节[]转换为“安全”string,例如:
 byte[] keyValue = new byte[] {…}; String key = javax.xml.bind.DatatypeConverter.printBase64Binary(keyValue); 
当然上面有很多变种,比如:
 String key = org.apache.commons.codec.binary.Base64.encodeBase64(keyValue);