【问题标题】:Using String(byte[]) as key to map使用 String(byte[]) 作为键映射
【发布时间】:2015-10-20 10:57:26
【问题描述】:

我有一个程序从返回为byte[] 的数据库中获取ID。我想使用这些 id(字节数组)作为映射的键。默认情况下这不起作用,因为比较的是“对象相等”而不是“内容相等”。

接下来我尝试了 似乎 的工作是使用 new String(byte[]) 构造函数实例化一个字符串。虽然这似乎有效,但我知道我正在做一些潜在的狡猾的事情。我没有指定依赖于系统默认值的编码。我也不知道是否所有字节序列在每种编码中都有表示。

为了执行map.put() 和map.get() 安全而将byte[]“转换”为String 是否安全?有没有我没有考虑过这种方法会无意中造成冲突的极端情况(其中 2 个不同的byte[] 具有不同的内容可能会变成相同的String)。

注意:地图存储在内存中,仅适用于单个应用程序运行。 如果这种方法可行,我编写的简单包装类可以让我的生活更轻松:

public class Cache {

    Map<String, Set<String>> cache = new HashMap<String, Set<String>>();

    public Cache() {}

    public void put(byte[] key, Set<String> value) {
        cache.put(new String(key), value);
    }

    public Set<String> get(byte[] key) {
        return cache.get(new String(key));
    }
}

【问题讨论】:

标签: java


【解决方案1】:

您能不能围绕您的 byte[] 数组构建一个简单的包装器?

类似于:

public class CacheKey {
    private final byte[] key;

    public CacheKey(byte[] key) {
        this.key = key; // You may want to do a defensive copy here
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        CacheKey cacheKey = (CacheKey) o;
        return Arrays.equals(key, cacheKey.key);
    }

    @Override
    public int hashCode() {
        return key != null ? Arrays.hashCode(key) : 0;
    }
}

并将其用作地图键?它会比使用内置的 String 对象更轻量级,并使键类型实际上更清晰。

【讨论】:

  • 嘿,这也可以。 Arrays.hashCode(prim[]) 是否根据数组的内容生成哈希?
  • 那个 hashcode 和 equals 方法实际上是由我的 IDE 生成的。 Arrays.hashcode() 保证在具有相同哈希码的两个数组之间调用 Arrays.equals() 将评估为真,所以它必须这样做。
【解决方案2】:

您可能应该使用Biginteger。它有一个BigInteger(byte[]) 构造函数,并且有一个有效的比较系统。

【讨论】:

  • 这看起来很简单。除非有明显的理由不这样做,否则我将继续这样做。我唯一能想到的问题是一个字节数组,其内容带有“前导”零,但这对我来说不应该是这样,因为这是现实。感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 2018-10-02
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
  • 1970-01-01
  • 2011-10-20
相关资源
最近更新 更多