Java Map<>内在类型可能吗?

时间:2011-10-24 07:14:15

标签: java hashmap

这怎么可能: HashMap<byte[], byte[]>和byte []的hash()是什么?

2 个答案:

答案 0 :(得分:12)

是的,这是可能的(有一个很大的警告,见下文),但byte[]不是“内在类型”。首先,没有这样的事情,你可能意味着“原始类型”。第二:byte[] 不是原始类型,byte是。数组始终是引用类型。

数组没有特定的hashCode实现,所以他们只使用hashCode of Object,这意味着hashCode将是the indentity-hashCode,这与Arrays.hashCode()无关实际内容。

换句话说:byte[]是一个非常糟糕的Map密钥,因为您只能使用完全相同的实例来检索该值。

如果您需要基于数组的基于内容的hashCode(),则可以使用Arrays.equals(),但这不会(直接)使用Map。还有{{3}}来检查内容是否相等。

可以byte[]包装在一个实现hashCode()equals()的瘦包装器对象中(使用上面提到的方法):

import java.util.Arrays;

public final class ArrayWrapper {
  private final byte[] data;
  private final int hash;

  public ArrayWrapper(final byte[] data) {
    // strictly speaking we should make a defensive copy here,
    // but I *assume* (and should document) that the argument
    // passed in here should not be changed
    this.data = data;
    this.hash = Arrays.hashCode(data);
  }

  @Override
  public int hashCode() {
    return hash
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof ArrayWrapper)) {
      return false;
    }
    ArrayWrapper other = (ArrayWrapper) o;
    return this.hash == other.hash && Arrays.equals(this.data, other.data);
  }
  // don't add getData to prevent having to do a defensive copy of data
}

使用此课程,您可以使用Map<ArrayWrapper,byte[]>

答案 1 :(得分:2)

对于数组hashCode()使用Object的默认实现 - 通常是某种形式的内部对象地址。因此,如果它是一个不同的数组,则HashMap中的键被认为是唯一的,而不是数组内容相等。

byte[] a = { 2, 3 };
byte[] b = { 2, 3 };
System.out.println(a.equals(b)); // false
Map<byte[], String> map = new HashMap<byte[], String>();
map.put(a, "A");
map.put(b, "B");
System.out.println(map); // {[B@37d2068d=B, [B@7ecec0c5=A}