使用单例访问 "constant global array" 是否合适?
Is it proper to use a singleton for access to a "constant global array"?
我有一个不需要修改的int数组。
该数组在代码为 运行 之前不可用,因为它使用文件中的一些数据,然后修改这些数据以生成数组值。
需要从许多 类 访问此数组。据我所知,一种糟糕的做法是不断地将数组传递给函数,另一种更糟糕的方法是声明为全局变量。
我的直觉也许我应该使用单例,它只会保存一个 int 数组和 return 在调用时该数组的一个实例。假设这是正确的,首先将该数组传递给单例并设置它的正确方法是什么。那么调用单例并拥有数组实例的正确方法是什么 returned?
谢谢
你这里的问题与数组是否全局无关。你几乎在用单身人士做同样的事情。全局变量的问题与共享状态有关,因为任何人都可以访问它们并弄乱它们。因此,很难推断此类变量的状态或其生命周期。
我建议将数组包装在它自己的 class 中。这实际上是您的单身人士。该数组将是一个静态成员。此外,不是 return 对数组本身的引用,而是 return 数组的 copy。这样就没有人可以直接修改数组了。
您的 class 可能如下所示:
//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);
}
}
老实说,这对我来说确实有点不雅和笨重。 相反,也许您可以尝试使用不可修改的列表 (Collections.unmodifiableList(List<? extends T> list)
)。 您提到这是一个二维数组,但您仍然可以使用不可修改的列表来做到这一点;你最终会得到 List<List<Integer>>
。首先构建内部列表(一行的值),然后将它们作为不可修改的列表插入到外部列表中。然后使外部列表本身成为不可修改的列表。您可以将此列表包装在其自身类型的对象中,这将是一个单例(有点像上面的数组示例)。然后,不是提供对二维数组或列表本身的访问,而是提供一个 get(row, column)
方法来从列表中检索元素。但是,如果您正在这样做,那么您可能会很好地将列表保留为常规列表,因为一旦初始化,任何人都无法修改它。
我有一个不需要修改的int数组。 该数组在代码为 运行 之前不可用,因为它使用文件中的一些数据,然后修改这些数据以生成数组值。
需要从许多 类 访问此数组。据我所知,一种糟糕的做法是不断地将数组传递给函数,另一种更糟糕的方法是声明为全局变量。
我的直觉也许我应该使用单例,它只会保存一个 int 数组和 return 在调用时该数组的一个实例。假设这是正确的,首先将该数组传递给单例并设置它的正确方法是什么。那么调用单例并拥有数组实例的正确方法是什么 returned?
谢谢
你这里的问题与数组是否全局无关。你几乎在用单身人士做同样的事情。全局变量的问题与共享状态有关,因为任何人都可以访问它们并弄乱它们。因此,很难推断此类变量的状态或其生命周期。
我建议将数组包装在它自己的 class 中。这实际上是您的单身人士。该数组将是一个静态成员。此外,不是 return 对数组本身的引用,而是 return 数组的 copy。这样就没有人可以直接修改数组了。
您的 class 可能如下所示:
//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);
}
}
老实说,这对我来说确实有点不雅和笨重。 相反,也许您可以尝试使用不可修改的列表 ( 您提到这是一个二维数组,但您仍然可以使用不可修改的列表来做到这一点;你最终会得到 Collections.unmodifiableList(List<? extends T> list)
)。List<List<Integer>>
。首先构建内部列表(一行的值),然后将它们作为不可修改的列表插入到外部列表中。然后使外部列表本身成为不可修改的列表。您可以将此列表包装在其自身类型的对象中,这将是一个单例(有点像上面的数组示例)。然后,不是提供对二维数组或列表本身的访问,而是提供一个 get(row, column)
方法来从列表中检索元素。但是,如果您正在这样做,那么您可能会很好地将列表保留为常规列表,因为一旦初始化,任何人都无法修改它。