Java中的不可变数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3700971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Immutable array in Java
提问by
Is there an immutable alternative to the primitive arrays in Java? Making a primitive array final
doesn't actually prevent one from doing something like
Java 中的原始数组是否有不可变的替代方案?制作原始数组final
实际上并不会阻止人们做类似的事情
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
I want the elements of the array to be unchangeable.
我希望数组的元素是不可更改的。
采纳答案by Jason S
Not with primitive arrays. You'll need to use a List or some other data structure:
不适用于原始数组。您需要使用 List 或其他一些数据结构:
List<Integer> items = Collections.unmodifiableList(Arrays.asList(0,1,2,3));
回答by Jason S
No, this is not possible. However, one could do something like this:
不,这是不可能的。但是,您可以执行以下操作:
List<Integer> temp = new ArrayList<Integer>();
temp.add(Integer.valueOf(0));
temp.add(Integer.valueOf(2));
temp.add(Integer.valueOf(3));
temp.add(Integer.valueOf(4));
List<Integer> immutable = Collections.unmodifiableList(temp);
This requires using wrappers, and is a List, not an array, but is the closest you will get.
这需要使用包装器,并且是一个列表,而不是一个数组,但它是您将得到的最接近的。
回答by Joachim Sauer
As others have noted, you can't have immutable arrays in Java.
正如其他人所指出的,Java 中不能有不可变数组。
If you absolutely need a method that returns an array that doesn't influence the original array, then you'd need to clone the array each time:
如果您绝对需要一个返回不影响原始数组的数组的方法,那么您每次都需要克隆该数组:
public int[] getFooArray() {
return fooArray == null ? null : fooArray.clone();
}
Obviously this is rather expensive (as you'll create a full copy each time you call the getter), but if you can't change the interface (to use a List
for example) and can't risk the client changing your internals, then it may be necessary.
显然这是相当昂贵的(因为你每次调用 getter 都会创建一个完整的副本),但是如果你不能改变接口(List
例如使用 a )并且不能冒险让客户改变你的内部,那么这可能是必要的。
This technique is called making a defensive copy.
这种技术称为制作防御性副本。
回答by ColinD
My recommendation is to not use an array or an unmodifiableList
but to use Guava's ImmutableList, which exists for this purpose.
我的建议是不要使用数组或 an ,unmodifiableList
而是使用Guava的ImmutableList,它就是为此目的而存在的。
ImmutableList<Integer> values = ImmutableList.of(0, 1, 2, 3);
回答by Thomas Mueller
If you need (for performance reason or to save memory) native 'int' instead of 'java.lang.Integer', then you would probably need to write your own wrapper class. There are various IntArray implementations on the net, but none (I found) was immutable: Koders IntArray, Lucene IntArray. There are probably others.
如果您需要(出于性能原因或为了节省内存)原生“int”而不是“java.lang.Integer”,那么您可能需要编写自己的包装类。网络上有各种 IntArray 实现,但没有一个(我发现)是不可变的:Koders IntArray、Lucene IntArray。可能还有其他人。
回答by Martin
Well.. arrays are useful to pass as constants (if they were) as variants parameters.
嗯.. 数组作为常量(如果是的话)作为变体参数传递很有用。
回答by Brigham
There is one way to make an immutable array in Java:
有一种方法可以在 Java 中创建不可变数组:
final String[] IMMUTABLE = new String[0];
Arrays with 0 elements (obviously) cannot be mutated.
具有 0 个元素(显然)的数组不能被改变。
This can actually come in handy if you are using the List.toArray
method to convert a List
to an array. Since even an empty array takes up some memory, you can save that memory allocation by creating a constant empty array, and always passing it to the toArray
method. That method will allocate a new array if the array you pass doesn't have enough space, but if it does (the list is empty), it will return the array you passed, allowing you to reuse that array any time you call toArray
on an empty List
.
如果您使用该List.toArray
方法将 a 转换List
为数组,这实际上会派上用场。由于即使是空数组也会占用一些内存,因此您可以通过创建一个常量空数组并始终将其传递给toArray
方法来保存该内存分配。该方法将分配一个新的数组,如果你传递数组没有足够的空间,但如果它(列表为空),它会回报你传递的数组,让您重新使用数组调用任何时间toArray
上的空的List
。
final static String[] EMPTY_STRING_ARRAY = new String[0];
List<String> emptyList = new ArrayList<String>();
return emptyList.toArray(EMPTY_STRING_ARRAY); // returns EMPTY_STRING_ARRAY
回答by aeracode
Another one answer
另一个答案
static class ImmutableArray<T> {
private final T[] array;
private ImmutableArray(T[] a){
array = Arrays.copyOf(a, a.length);
}
public static <T> ImmutableArray<T> from(T[] a){
return new ImmutableArray<T>(a);
}
public T get(int index){
return array[index];
}
}
{
final ImmutableArray<String> sample = ImmutableArray.from(new String[]{"a", "b", "c"});
}
回答by kevinarpe
In some situations, it will be lighter weight to use this static method from Google Guava library: List<Integer> Ints.asList(int... backingArray)
在某些情况下,使用 Google Guava 库中的这个静态方法会更轻: List<Integer> Ints.asList(int... backingArray)
Examples:
例子:
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
回答by Display Name
If you want to avoid both mutability and boxing, there is no way out of the box. But you can create a class which holds primitive array inside and provides read-only access to elements via method(s).
如果您想同时避免可变性和装箱,则没有开箱即用的方法。但是您可以创建一个类,其中包含原始数组并通过方法提供对元素的只读访问。