【问题标题】:What's the proper collection for indexing with several objects?使用多个对象进行索引的正确集合是什么?
【发布时间】:2016-08-24 11:31:27
【问题描述】:

假设我有这个数组:

double[][] Q = new double[n1][n2];

我可以使用int 索引来索引Q 的值,例如Q[2][1]。但就我而言,n1byte[],而不是int。我仍然知道n1 的可能值(例如,数组值的所有可能组合)。我应该使用什么集合而不是array

HashMap<byte[], Double>[] Q = new HashMap[n2];

这是我的解决方案,但我不确定它是否足够。要索引,我可以做

byte[] n1 = {1,0,6,1,4,2,5,1};
Q[1].get(n1);

有没有更好的方法来做到这一点?性能更高的东西?我认为拥有一个 HashMaps 数组并不理想,但我可以将 int 添加到我的密钥中吗?怎么样?


如 cmets 所述,

使用数组作为哈希映射键的问题(除了它是可变的)是数组不会根据它们的内容计算它们的哈希码;因此,除非您有实际的键实例,否则您实际上无法在地图中查找值。

那么如何使用数组作为索引键呢?一个愚蠢的解决方案是在使用它之前始终将其转换为 String,但我相信有更好和更合适的解决方案。

【问题讨论】:

  • intbyte 宽,那么使用二维数组有什么问题呢?当然,使用另一种数据结构可能会更好地解决您的问题。
  • 使用数组作为哈希映射键的问题(除了它是可变的)是数组不会根据它们的内容计算它们的哈希码;因此,除非您有实际的键实例,否则您实际上无法在地图中查找值。
  • 啊!那么如何使用数组进行索引呢?我是否必须每次都将其转换为String?这样做的正确方法是什么?
  • 您可以将其包装在另一个类中,该类使用数组的内容覆盖equalshashCode,并将其用作键。
  • 这些字节数组是做什么用的?

标签: java collections


【解决方案1】:

我认为解决你的问题最好的方法是定义一个复杂的键类,它基本上由你的 byte[] 和 int 组成,为这个类编写可靠的 hashCode 和 equals-Methods,并将其用作键HashMap。

这样,您可以使用 hashmap 的运行时和内存效率,并将键的复杂性封装在单独的类中。

代码说明:

public static class MyKey {
    private int    i;
    private byte[] b;

    private MyKey(int i, byte[] b) {
        this.i = i;
        this.b = b;
    }

    public static MyKey of(int i, byte ... b) {
        return new MyKey(i, b);
    }

    @Override
    public int hashCode() {  // Autogenerated from eclipse
        final int prime = 31;
        int result = 1;
        result = prime * result + Arrays.hashCode(b);
        result = prime * result + i;
        return result;
    }

    @Override
    public boolean equals(Object obj) {  // Autogenerated from eclipse
        if(this == obj)
            return true;
        if(obj == null)
            return false;
        if(getClass() != obj.getClass())
            return false;
        MyKey other = (MyKey) obj;
        if(!Arrays.equals(b, other.b))
            return false;
        if(i != other.i)
            return false;
        return true;
    }
}

public static void main(String[] args) {
    HashMap<MyKey, Double> valueMap = new HashMap<>();
    valueMap.put(MyKey.of(1, (byte)2, (byte)4, (byte)7), 0.1);
    valueMap.put(MyKey.of(1, new byte[] { 3, 8, 14 }), 0.1);
}

【讨论】:

  • 使用 i 变量的目的是什么?
  • 请注意,您应该在构造函数中对b进行防御性复制,以确保类所持有的数组在创建后不会被篡改。此外,类应该是final,成员变量也应该是,以使其真正不可变。
  • i 变量表示 OP 问题中的 int-index。因此,这样一个复杂的键类可以代替完整的索引。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
相关资源
最近更新 更多