如果我们在父List中添加元素,为什么JDK会向UnmodifyableList添加一个元素

时间:2015-12-24 23:23:19

标签: java collections

 List<Person> intList = new ArrayList<Person>();
        // creating Parent List
        // Person Class contains two fields Name and Age
        Person p1 = new Person("James", 28);
        Person p2 = new Person("Duncan", 26);
        Person p3 = new Person("Lukan",32);
        Person p4 = new Person("Therry", 12);
        // Creating ParentList
        intList.add(p1);
        intList.add(p2);        
        intList.add(p3);
        intList.add(p4);

        ImmutableList<Person> immutableList = ImmutableList.copyOf(intList);        
        List<Person> unModifybale = Collections.unmodifiableList(intList);
        //Adding element to parentList
        intList.add(p4);        

        System.out.println("\n" +intList);  

        // Here unModifyble List also gets element after added in parent list
        // why does it happen like this?

        System.out.println("\n unModifyble"+ unModifybale);

        System.out.println("\n Immutable" + immutableList)

3 个答案:

答案 0 :(得分:6)

来自the Javadoc

  

返回指定列表的不可修改视图。

您已在原始列表中创建视图 - 对原始列表的更改将通过视图反映出来。

答案 1 :(得分:1)

添加到@Oliver回答

  

来自the Javadoc

     
    

返回指定列表的不可修改视图。

  
     

您已在原始列表中创建视图 - 更改为   原始列表将通过视图反映出来。

基本上所有更新操作(如add,remove等)都被禁用并重写以抛出UnsupportedOperationException。 正在使用只读操作来装饰列表。 DECORATOR PATTERN 的一个例子。

//all update kind of operations method body
throw new UnsupportedOperationException();

创建不可修改的列表时,它不会复制列表的元素。相反,它存储列表的引用。当您遍历不可修改的列表时,它会将迭代器返回到实际列表。

Collections.unmodifiableList内部使用UnmodifiableCollection构造函数。您可以在以下提取的代码中看到它存储对集合的引用。

    //reference variable for the list
    final Collection<? extends E> c;

    UnmodifiableCollection(Collection<? extends E> c) {
        if (c==null)
            throw new NullPointerException();
        this.c = c; // storing the reference
    }

因此,正如@Oliver所提到的,不可修改的列表就像一个视图,意味着你无法通过视图更新列表,但只能查看。

答案 2 :(得分:0)

你写道:

  

“然后我希望UnmodifyableView在向原始List添加元素后不会受到影响,因为不可修改的viewList本身就是一个对象,表示来自OriginalList的List或CopyOfElements”。

这似乎是你误解的核心。

视图列表确实是一个Object。但是,它不代表原始列表 1 的时间快照。相反,它“代表” 2 基础列表,因为它现在是

1 - 如果这是此API的意图,他们会在javadocs中明确说明。

2 - 我不确定“代表”这个词是否正确。我会在列表数据结构表示物理世界中的某些内容的情况下使用“表示”,或者在应用程序“建模”的概念空间中使用某些表达式。在此上下文中,概念上不可修改的视图列表&gt;&gt;是&lt;&lt;它是视图的列表。事实上,可能是您对“代表”这个词的错误应用是造成混淆的根本原因。