Reputation: 425
I have an array of int which doesn't need to be modified. The array is not available until the code is run as it uses some data from a file which it then modifies to generate the array values.
This array needs to be accessed from many classes. To my knowledge a poor way of doing this would be to constantly pass the array to functions, another worse way would be to declare as a global variable.
I have the intuition that maybe I should use a singleton, it would only hold an array of int and return an instance of that array when called. Assuming this is correct, what is the proper way to firstly pass that array to the singleton once and have it be set. Then what is the proper way to call the singleton and have an instance of the array returned?
Thanks
Upvotes: 1
Views: 426
Reputation: 95528
Your issue here doesn't have to do with whether the array is global or not. You're pretty much doing the same thing with a singleton. Issues with global variables have to do with shared state, since anyone can access them and mess with them. Hence, it becomes very hard to reason about the state of such a variable or its life-cycle.
I would suggest wrapping the array inside a class of its own. This is, in effect, your singleton. The array would be a static member. Furthermore, instead of returning a reference to the array itself, return a copy of the array instead. This way no one can modify the array directly.
Your class could look like this:
//pick a better name; this is just for demo purposes
public class Singleton {
private static int[] array = {};
private static boolean initialized = false;
public static void initialize(int[] arr) {
if(!initialized) {
array = new int[arr.length];
System.arraycopy(arr, 0, array, 0, arr.length);
initialized = true;
} else {
throw new IllegalStateException("Array has already been initialized");
}
}
public static int[] getArray() {
return Arrays.copyOf(array, array.length);
}
}
To be honest, this does seem a little inelegant and bulky with me. Instead, perhaps you can try using an unmodifiable list ( You mentioned that this was a 2D array, but you can still do this with unmodifiable lists; you'd just end up with Collections.unmodifiableList(List<? extends T> list)
).List<List<Integer>>
. Build up the inner lists first (values for a row), and then insert them into the outer list as unmodifiable lists. Then make the outer list itself an unmodifiable list. You can wrap this list inside an object of its own type, which would be a singleton (kind of like the array example above). Then, instead of giving access to a 2D array or the list itself, provide a get(row, column)
method that retrieves an element from the lists. However, if you're doing this then you're probably fine leaving the the list as a regular list since there is no way anyone can modify it once initialized.
Upvotes: 1