【问题标题】:Why can't we increase size of ArrayList object returned by asList()?为什么我们不能增加 asList() 返回的 ArrayList 对象的大小?
【发布时间】:2019-03-23 19:55:11
【问题描述】:

我正在经历Arrays.asList()的实现。如果我们尝试通过List(I)特定方法更改数组的大小,则得到RE:UnsupportedException。 实施 -

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

根据上面的实现,asList返回一个ArrayList对象,为什么不能改变返回的List对象的大小呢?

具体来说,是什么阻止了更改返回的ArrayList 对象的大小?

任何线索都会有所帮助和赞赏。

【问题讨论】:

  • 您确定使用的是确切的重载吗?它有多个iirc。
  • 是的,这就是 java.util.Arrays 中给出的;
  • 这是我查看源代码时看到的返回值:return new Arrays.ArrayList(a)。这不是一个普通的 ArrayList。
  • 这是一个不同的类,恰好也被称为ArrayList
  • System.out.println(asList().getClass()).

标签: java arrays list arraylist


【解决方案1】:

Arrays.asList() 返回的List 部分不可变。一些变异操作被实现了,而另一些则没有。基本上,所有写入底层数组的操作都已实现。未实现需要重新分配新数组的操作。 set() 例如已实现,add() 未实现。如果您需要一个适当的List 在所有方面都可变:

List<T> myList = asList(v1, v2, v3); // Immutable
List<T> myList = new ArrayList<>(asList(v1, v2, v3)); // Mutable

Arrays.asList() 返回的List 不是“正常”(java.util.)ArrayList。一个普通的ArrayList 可以通过重新分配其支持数组来增长,这意味着它是一个由数组支持但具有所有List 功能可用的正确List

Arrays.asList() 返回的List 是原始数组上的“List 视图”。它不能增长,因为这会失去与原始数组的链接。下面的代码演示了这一点:

String[] data = { "foo", "bar" };
List<String> values = Arrays.asList(data);
System.err.println(values); // [foo, bar]
data[0] = "buzz";
values.set(1, "quak");
System.err.println(values); // [buzz, quak]
System.err.println(Arrays.toString(data)); // [buzz, quak]

【讨论】:

  • 它是不可变的。调用set() 会抛出异常。
  • 我收回它,它是可变的。感谢您指出了这一点。我没有意识到它是如此不一致。
  • 并不矛盾。 Arrays.asList 文档说它“返回一个由指定数组支持的固定大小的列表”。 addremove 方法本质上需要一个可变大小的列表。您可以使用set(和get)的原因是因为它就像通过索引访问数组一样,只不过它不是数组而是ListAbstractList 对此有所解释:“要实现可修改列表,[您] 必须另外覆盖 set(int, E) 方法 [...] 如果列表是可变大小的 [您] 必须另外覆盖 add(int, E) 和 remove(int) 方法。".
  • @Slaw 感谢您的指点,我已经相应地更新了答案。
猜你喜欢
  • 1970-01-01
  • 2011-06-28
  • 1970-01-01
  • 2023-04-10
  • 2022-11-01
  • 1970-01-01
  • 2017-06-26
  • 1970-01-01
相关资源
最近更新 更多