shi*_*har 72 java bytearray hashmap
你看到使用字节数组作为Map键有什么问题吗?我也可以做new String(byte[])和哈希,String但它更直接使用byte[].
Jon*_*eet 72
没关系,只要你只需要你的密钥的引用相等 - 数组不会以你可能想要的方式实现"值相等".例如:
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());
Run Code Online (Sandbox Code Playgroud)
打印像:
false
1671711
11394033
Run Code Online (Sandbox Code Playgroud)
(实际数字无关紧要;它们不同的事实很重要.)
假设你真的想要相等,我建议你创建自己的包装器,它包含一个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);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果在使用之后更改字节数组中的值ByteArrayWrapper,作为HashMap(等)中的键,您将无法再次查找该键... ByteArrayWrapper如果您需要,可以在构造函数中获取数据的副本,但是如果您知道不会更改字节数组的内容,那么这显然会浪费性能.
编辑:正如评论中所提到的,你也可以使用ByteBuffer它(特别是它的ByteBuffer#wrap(byte[])方法).考虑到ByteBuffer你不需要的所有额外能力,我不知道它是否真的是正确的,但这是一个选择.
Kat*_*one 60
问题是byte[]使用对象标识equals和hashCode,所以
byte[] b1 = {1, 2, 3}
byte[] b2 = {1, 2, 3}
Run Code Online (Sandbox Code Playgroud)
不会匹配的HashMap.我看到三个选择:
String,但是你必须要小心编码问题(你需要确保字节 - > String - > byte给你相同的字节).List<Byte>(在内存中可能很昂贵).hashCode和equals使用字节数组的内容.byt*_*ray 41
我们可以使用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)));
Run Code Online (Sandbox Code Playgroud)
将打印
true
Run Code Online (Sandbox Code Playgroud)
Art*_*rov 12
你可以用java.math.BigInteger.它有一个BigInteger(byte[] val)构造函数.它是一个引用类型,因此可以用作哈希表的键.和.equals()和.hashCode()被定义为用于各个整数,这意味着具有BigInteger的一致等于语义byte []数组.
我很惊讶答案没有指出最简单的选择。
是的,不可能使用 HashMap,但没有人阻止您使用 SortedMap 作为替代方案。唯一的事情是编写一个需要比较数组的比较器。它的性能不如 HashMap,但如果您想要一个简单的替代方案,那么您可以使用(如果您想隐藏实现,可以将 SortedMap 替换为 Map):
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;
}
}
Run Code Online (Sandbox Code Playgroud)
此实现可以针对其他数组进行调整,您唯一必须注意的是相等的数组(= 相等的长度和相等的成员)必须返回 0 并且您具有确定性顺序
| 归档时间: |
|
| 查看次数: |
62158 次 |
| 最近记录: |