Что касается неизменяемой коллекции

1

Рассмотрим следующий ниже код

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Integer> intList1=new ArrayList<Integer>();
        List<Integer> intList2;
        intList1.add(1);
        intList1.add(2);
        intList1.add(3);
        intList2=Collections.unmodifiableList(intList1);
        intList1.add(4);

        for(int i=0;i<4;i++)
        {
            System.out.println(intList2.get(i));
        }
    }

}

Результатом приведенного выше кода является

1
2
3
4

В приведенном выше коде мы создаем неизменяемый List intList2 из содержимого List intList 1. Но после Collections.unmodifiable заявления, когда я внести изменения в intList1, что изменение отражает в intList2. Как это возможно?

Теги:
collections

5 ответов

3

Вам необходимо прочитать Javadoc для Collections.unmodifiableList

Возвращает немодифицируемое представление указанного списка.

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

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

Чтобы создать действительно немодифицируемую коллекцию, вам нужно будет скопировать и обернуть:

intList2=Collections.unmodifiableList(new ArrayList<>(intList1));

Это копирует содержимое intList1 в другую коллекцию, а затем обертывает эту коллекцию в неизменяемой переменной. Нет ссылки на обернутую коллекцию.

Это дорого - весь базовый хранилище данных (массив в этом случае) необходимо дублировать, который (как правило) принимает O(n).

Google Guava предоставляет непреложные коллекции, которые решают некоторые проблемы создания защитных копий:

  • Если коллекция уже неизменна, она не копируется снова
  • Предоставьте интерфейс, который может быть использован для явного указания, что коллекция является неизменной
  • Предоставлять множество статических заводских методов для создания неизменных коллекций

Но скорость все еще остается главной проблемой при использовании неизменяемых копий коллекций, а не неизменяемых представлений.

Следует отметить, что обычное использование Collections.unmodifiableXXX - это возврат из метода, например, getter:

public Collection<Thing> getThings() {
    return Collections.unmodifiableCollection(things);
}

В этом случае можно отметить две вещи:

  1. Пользователь getThings не может получить доступ к things поэтому getThings не может быть нарушена.
  2. Было бы очень дорого копировать things каждый раз, когда вызывал геттер.

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

  • 0
    Спасибо Борис ... это прояснило мои сомнения.
  • 0
    @harrypotter просматривая свой профиль, вы задали несколько вопросов, но не приняли никаких ответов ; пожалуйста, исправьте это.
1

Collections.unmodifiableList возвращает вид "только для чтения" внутреннего списка. Хотя возвращаемый объект не модифицируется, исходный список, который он ссылается, может быть изменен. Оба объекта указывают на один и тот же объект в памяти, чтобы он отражал сделанные изменения.

Вот хорошее объяснение того, что происходит.

1

Из Javadoc of Collections.unmodifiableList:

Возвращает немодифицируемое представление указанного списка. Этот метод позволяет модулям предоставлять пользователям доступ к внутренним спискам "только для чтения".

Это предотвращает изменение возвращаемого списка, но сам исходный список по-прежнему может быть.

0

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

0

В вашем коде вы

 intList2=Collections.unmodifiableList(intList1);

создание unmodifiableList в intList2. Таким образом, вы можете вносить изменения в inList1, но вам не разрешено делать какие-либо изменения в intList2

попробуйте это: intList2.add(4); ты получишь

 java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Unknown Source)

выше исключения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню