Неизменяемый массив в Java - PullRequest
141 голосов
/ 13 сентября 2010

Есть ли неизменная альтернатива примитивным массивам в Java? Создание примитивного массива final на самом деле не мешает делать что-то вроде

final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;

Я хочу, чтобы элементы массива были неизменяемыми.

Ответы [ 14 ]

1 голос
/ 13 сентября 2010

Нет, это невозможно.Тем не менее, можно сделать что-то вроде этого:

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);

Это требует использования обёрток и представляет собой список, а не массив, но ближайший к вам.

0 голосов
/ 14 декабря 2017

Метод of (E ... elements) в Java9 можно использовать для создания неизменяемого списка, используя только строку:

List<Integer> items = List.of(1,2,3,4,5);

Приведенный выше метод возвращает неизменный список, содержащий произвольное количество элементов. И добавление любого целого числа в этот список приведет к исключению java.lang.UnsupportedOperationException. Этот метод также принимает один массив в качестве аргумента.

String[] array = ... ;
List<String[]> list = List.<String[]>of(array);
0 голосов
/ 22 июля 2014

Несмотря на то, что Collections.unmodifiableList() работает, иногда у вас может быть большая библиотека с уже определенными методами для возврата массивов (например, String[]). Чтобы предотвратить их нарушение, вы можете определить вспомогательные массивы, в которых будут храниться значения:

public class Test {
    private final String[] original;
    private final String[] auxiliary;
    /** constructor */
    public Test(String[] _values) {
        original = new String[_values.length];
        // Pre-allocated array.
        auxiliary = new String[_values.length];
        System.arraycopy(_values, 0, original, 0, _values.length);
    }
    /** Get array values. */
    public String[] getValues() {
        // No need to call clone() - we pre-allocated auxiliary.
        System.arraycopy(original, 0, auxiliary, 0, original.length);
        return auxiliary;
    }
}

Для проверки:

    Test test = new Test(new String[]{"a", "b", "C"});
    System.out.println(Arrays.asList(test.getValues()));
    String[] values = test.getValues();
    values[0] = "foobar";
    // At this point, "foobar" exist in "auxiliary" but since we are 
    // copying "original" to "auxiliary" for each call, the next line
    // will print the original values "a", "b", "c".
    System.out.println(Arrays.asList(test.getValues()));

Не идеально, но, по крайней мере, у вас есть «псевдо неизменяемые массивы» (с точки зрения класса), и это не сломает связанный код.

0 голосов
/ 18 февраля 2011

Хорошо ... массивы полезно передавать как константы (если они были) как параметры вариантов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...