1

在 Java 中,我有一个类:

public static class Key {

    int[] vector = null;

    private int hashcode = 0;

    Key (int[] key) {
        vector = new int[key.length];
        // here is the problem
        System.arraycopy(key, 0, vector, 0, key.length);
    }

    public int hashCode() { ... }

    public boolean equals(Object o) { ... }

}

它充当HashMap<Key, int[]> map. 在我做的代码中:

// value int[] array is filled before
map.put(new Key(new int[] {5, 7}), value);

但这会创建一个参数数组{5, 7}两次 - 第一次Key是在调用构造函数时,然后在该构造函数内部。

我不能使用HashMap<int[], int[]> map,因为那时还不清楚hashCode将用于什么int[]。所以我把int[]钥匙包在Key课堂上。

怎么可能只创建一次参数数组(可以是不同大小的)?

我不喜欢这个解决方案:

map.put(new Key(5, 7), value);

// and rewrite the constructor
Key (int a1, int a2) {
    vector = new int[2];
    vector[0] = a1;
    vector[1] = a2;
}

因为通常参数数组可以具有各种大小。

4

3 回答 3

3

怎么可能只创建一次参数数组(可以是不同大小的)?

不幸的是,您不能这样做,因为没有办法使内置 Java 数组不可变。如果可以制作不可变数组,则以下内容将起作用:

Key (int[] key) {
    // Do not do this!!!
    vector = key;
}

尽管上述方法可以在完全合作的环境中工作,但恶意用户可以传递一个数组,让密钥计算哈希,然后更改数组元素以将错误引入您的代码。这就是为什么当你决定复制传入的数组时你是绝对正确的。

您可以更改函数以接受可变数量的参数,如下所示:

Key (int ... key) {
    vector = new int[key.length];
    System.arraycopy(key, 0, vector, 0, key.length);
}

这将允许您隐式而不是显式地创建数组:

map.put(new Key(5, 7), value);
于 2013-03-18T01:24:21.537 回答
1

使用可变参数作为参数并使用Arrays.copyOf()

Key (int... key) {
    vector = Arrays.copyOf(key, key.length);
}

现在你可以用任何数量的 int 参数调用构造函数(包括没有参数),它不会导致错误。

于 2013-03-18T01:23:51.353 回答
1

由于arraycopy用于从一个对象到另一个对象进行深度复制,因此在某些时候您需要创建两个对象,其中第二个对象的大小与参数数组的大小相同。所以vector = new int[key.length];看起来是正确的。

顺便说一句,当我编译你的代码时,我得到一个错误,static它不是类的有效修饰符,只有public,abstractfinalare。

于 2013-03-18T01:28:46.590 回答