什么是使用多个对象进行索引的正确集合?

时间:2016-08-24 11:31:27

标签: java collections

假设我有这个数组:

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

我可以使用Q索引(例如int)索引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添加到我的密钥中吗?怎么样?

如评论中所述,

  

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

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

1 个答案:

答案 0 :(得分:0)

我认为解决问题的最佳方法是定义一个复杂的密钥类,它基本上由您的byte []和int组成,为此类编写可靠的hashCode和equals-Methods,并将其用作密钥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);
}