CopiesList.addAll方法抛出UnsupportedOperationException

时间:2017-11-02 09:17:09

标签: java

< obj.length

输出

List<String> hi = Collections.nCopies(10, "Hi");
List<String> are = Collections.nCopies(10, "Are");

hi.addAll(are);

hi.forEach(System.out::println);

我认为AbstractList.add()在JDK中没有实现。这就是它无法正常工作的原因。

但是,如果我使用CopiesList对象创建一个新的ArrayList对象,它可以工作,因为它将有一个正确的add()实现。

我的问题是:为什么Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.add(Unknown Source) at java.util.AbstractList.add(Unknown Source) at java.util.AbstractCollection.addAll(Unknown Source) at com.practice.java8.lambdaexp.Test.main(Test.java:14) 没有适当的addAll实现?

2 个答案:

答案 0 :(得分:5)

Collections.nCopies会返回一个不可变的List,因此您无法向其中添加任何内容:

  

返回不可变列表,其中包含n个指定对象的副本。

它返回一个不可变的List,因为它只包含您传递给构造函数的元素的单个引用:

  

新分配的数据对象很小(它包含对数据对象的单个引用)。

这样做是为了提高性能和存储要求 - Collections.nCopies(10, "Hi")Collections.nCopies(10000000, "Hi")占用相同的空间。

因此将它实现为可变列表是非常困难的。例如,如果没有为该元素分配存储空间,您将如何将10000'元素设置为某个新值?

如果你需要一个包含同一对象副本的可变List,你必须将不可变List传递给一些可变的List构造函数:

List<String> mutable = new ArrayList<>(Collections.nCopies(10, "Hi"));

答案 1 :(得分:4)

正如JavaDoc所说,返回的列表是不可变的,这意味着您无法修改它:

  

[nCopies]返回由指定对象的n个副本组成的不可变列表。

也许你没有得到&#34;与List.addAll&#34;部分。您必须有一个非不可变列表,您可以在其中添加所有元素:

List modifiableList = new ArrayList<String>();

List<String> hi = Collections.nCopies(10, "Hi");
List<String> are = Collections.nCopies(10, "Are");

modifiableList.addAll(are);
modifiableList.addAll(hi);

modifiableList.forEach(System.out::println);