Как вернуть постоянную коллекцию

Есть ли в Java способ вернуть ссылку на коллекцию классов, где я не могу ни изменить ее, ни изменить данные ее элементов?

Так что, если у меня есть карта Map<Integer, Set<String>> тело не может получить ссылку на установленное значение и добавить элементы к нему?

4 ответа

Решение

Единственный способ гарантировать, что все объекты внутри Mapне может быть изменено, даже если Map само по себе неизменяемым, было бы сделать сами объекты неизменяемыми.

unmodifiableMap() метод гарантирует, что Map не может быть изменено, но это не дает никаких гарантий относительно объектов, которые он содержит. Взгляните на это, чтобы иметь представление о том, как сделать объект неизменным. Для конкретного примера посмотрите, как String класс работает: вы не можете изменять символы внутри строки и все методы, которые могут изменить строку (например: toUpperCase()) действительно вернуть новую строку. Это поведение, которое вы хотите для объектов внутри вашего Map,

Учитывая, что карта в вопросе содержит Set<String> в качестве его значений, затем с помощью Collections.unmodifiableSet() на наборах перед добавлением их на карту сделает их неизменными, потому что String, как указано выше, уже неизменен.

Ты можешь использовать Collections.unmodifiableMap чтобы получить карту, которую нельзя изменить.

Есть разные методы для каждого типа коллекции:

  • unmodifiableCollection возвращает неизменяемое представление универсальной коллекции
  • unmodifiableSet возвращает неизменяемое представление набора
  • unmodifiableList возвращает неизменяемое представление списка
  • unmodifiableSortedSet возвращает неизменяемое представление SortedSet
  • unmodifiableSortedMap возвращает неизменяемое представление SortedMap

Если элементы сами являются коллекциями, вы можете написать рекурсивный метод для создания новой коллекции, которая содержит неизменяемые представления исходных элементов.

В общем, если элементы, которые вы храните в коллекции, сами могут быть изменены, ничто не мешает вам делать это, за исключением создания защитных копий.

Вероятно, проще всего достичь своей цели, обеспечив доступ к внешней коллекции (Map) с помощью вашего собственного метода (ов). Затем вы можете вернуть соответствующий Set объект после прохождения его через Collections.unmodifiableSet(),

поскольку String является неизменным, после этого вызывающим абонентам ничего не остается изменить.

Если не считать этого, вам придется построить новый Map заполнены множествами, все прошли через Collections.unmodifiableSet() а затем передать это через Collections.unmodifiableMap(), Но это может быть, а может и не быть хорошей идеей в зависимости от размера вашей коллекции.

Карта:

Map<Integer, String> myMap =
            Collections.unmodifiableMap(new HashMap<Integer, String>() {
        {
            put(1, "value1");
            put(2, "value2");
            put(3, "value3");
        }
    });

Список:

List<String> list = Collections.unmodifiableList(new ArrayList<String>() {
        {
            add("value1");
            add("value2");
            add("value3");
        }
    });

Задавать:

Set<String> list = Collections.unmodifiableSet(new HashSet<String>() {
        {
            add("value1");
            add("value2");
            add("value3");
        }
    });
Другие вопросы по тегам