Reputation: 4556
In Java, I have a class:
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) { ... }
}
which acts as a key in the HashMap<Key, int[]> map
. In code I do:
// value int[] array is filled before
map.put(new Key(new int[] {5, 7}), value);
But this creates an argument array {5, 7}
twice - first time when Key
constructor is called and then inside that constructor.
I can not use HashMap<int[], int[]> map
because then it is not clear what hashCode
will be used for int[]
. So I wrap up the int[]
key inside Key
class.
How is it possible to create an argument array (which can be of different size) just once?
I do not like this solution:
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;
}
because generally an argument array can be of various size.
Upvotes: 1
Views: 621
Reputation: 2698
Since arraycopy
is being used to do a deep copy from one object to another, at some point you need to create two objects where the second is the same size as the argument array. So vector = new int[key.length];
looks correct.
Btw, when I compile your code I get an error that static
is not a valid modifier for class, only public
, abstract
, or final
are.
Upvotes: 1
Reputation: 726987
How is it possible to create an argument array (which can be of different size) just once?
Unfortunately, you cannot do that, because there is no way to make a built-in Java array immutable. If it were possible to make immutable arrays, the following would work:
Key (int[] key) {
// Do not do this!!!
vector = key;
}
Although the above would work in fully cooperative environments, hostile users could pass an array, and let the key calculate the hash, and then change array elements to introduce errors into your code. That's why you are absolutely right when you decided to copy the array passed in.
You can change the function to accept variable number of arguments, like this:
Key (int ... key) {
vector = new int[key.length];
System.arraycopy(key, 0, vector, 0, key.length);
}
This would let you create arrays implicitly rather than explicitly:
map.put(new Key(5, 7), value);
Upvotes: 3
Reputation: 425308
Use varargs for the parameter and use Arrays.copyOf()
:
Key (int... key) {
vector = Arrays.copyOf(key, key.length);
}
Now you can call the constructor with any number if int parameters (including no parameters) and it won't cause an error.
Upvotes: 1