【问题标题】:Create mutable List from array?从数组创建可变列表?
【发布时间】:2012-07-24 10:36:30
【问题描述】:

我有一个数组我想变成List,以便修改数组的内容。

Stack Overflow 有很多针对 Arrays.asList() 的问题/答案,以及它如何仅提供底层数组的列表视图,以及如何尝试操作结果列表通常会抛出 UnsupportedOperationException 作为用于操作Arrays.asList()提供的List实现没有实现list(例如add()remove()等)。

但我找不到如何将数组转换为可变列表的示例。我想我可以将数组和put() 每个值循环到一个新的列表中,但我想知道是否有一个接口可以为我执行此操作。

【问题讨论】:

    标签: java arrays list mutable


    【解决方案1】:

    一种简单的方法:

    Foo[] array = ...;
    List<Foo> list = new ArrayList<Foo>(Arrays.asList(array));
    

    这将创建一个可变列表 - 但它将是原始数组的副本。更改列表将不会更改数组。当然,您可以稍后将其复制回来,使用toArray

    如果你想在数组上创建一个可变的view,我相信你必须自己实现。

    【讨论】:

    • Arrays.asList 返回一个数组视图,支持不影响列表大小的变异方法
    • @jon-skeet 我知道,我只是说 Arrays.asList 为您提供了一个可变性有限的数组支持列表,如果您需要添加/删除/插入,那么 ArrayList 包装是一种更好的方法。
    • Java 需要在所有这些静态工厂方法中明确可变性/不变性。发现你在运行时做了一个不可变的东西真是太可惜了。
    • @dustinevan:文档非常清楚 IMO:“返回由指定数组支持的固定大小的列表。(更改返回的列表“写入”到数组。)”
    • @JonSkeet 不想浪费你的时间——感谢你所做的一切。我只想投票以使名称本身更加清晰-我相信文档很清楚。我们中的一些人在语言之间跳舞,这在其他语言中相当清楚。
    【解决方案2】:
    myNewArrayList = new ArrayList<>(Arrays.asList(myArray));
    

    【讨论】:

    • @JonSkeet 我知道你的评论来自 2012 年,我现在生活在未来,但考虑到我的 IDE 特别强调并说“嘿, 不要用声明的类型声明它。你不需要它”?
    • @BrentThoenen:我不明白你的评论。您是否注意到我的评论提到了修订版 1,它使用了 myNewArrayList = new ArrayList(...),即原始类型? “使用菱形运算符让编译器计算出类型参数”和“使用原始类型”是有区别的。
    • 我发布了这个答案并且一直生活在@JonSkeet 本人对我的答案的评论中。感谢布伦特的评论。
    • @JonSkeet 啊,我的错。我没有检查你评论的版本。我做了一个错误的假设,即 2012 java 将空菱形运算符也假定为原始类型。那是我的b。谢谢你的回答!
    【解决方案3】:

    如果您使用的是 google 集合 API (Guava):

    Lists.newArrayList(myArray);
    

    【讨论】:

    • 这是最简洁的答案。谢谢。
    • 甚至 Guava 本身也建议使用 new ArrayList&lt;&gt;(Arrays.asList(...)) - 该方法的 javadoc 暗示它将被弃用,因为它不够用。
    • 2020,但仍未弃用。跳进去!
    【解决方案4】:

    如果您使用的是Eclipse Collections(以前的GS Collections),则可以使用FastList.newListWith(...)FastList.wrapCopy(...)

    这两种方法都采用可变参数,因此您可以内联创建数组或传入现有数组。

    MutableList<Integer> list1 = FastList.newListWith(1, 2, 3, 4);
    
    Integer[] array2 = {1, 2, 3, 4};
    MutableList<Integer> list2 = FastList.newListWith(array2);
    

    这两种方法的区别在于数组是否被复制。 newListWith() 不复制数组,因此需要固定时间。如果您知道数组可能在其他地方发生突变,则应避免使用它。

    Integer[] array2 = {1, 2, 3, 4};
    MutableList<Integer> list2 = FastList.newListWith(array2);
    array2[1] = 5;
    Assert.assertEquals(FastList.newListWith(1, 5, 3, 4), list2);
    
    Integer[] array3 = {1, 2, 3, 4};
    MutableList<Integer> list3 = FastList.wrapCopy(array3);
    array3[1] = 5;
    Assert.assertEquals(FastList.newListWith(1, 2, 3, 4), list3);
    

    注意:我是 Eclipse Collections 的提交者。

    【讨论】:

    • 这是一个不错的集合 API。我看到的第一个可能会诱使我远离我自己的实现......我发现通常有用的似乎缺少的唯一东西是由数组支持的排序集实现(我发现它比对于很少修改的数据或可能经常修改但通常包含少于 10 个左右元素的集合的基于树的实现。
    【解决方案5】:

    这个使用 Java 8 中包含的 Stream API 的简单代码创建了一个包含数组元素的可变列表(或视图):

    Foo[] array = ...;
    List<Foo> list = Stream.of(array).collect(Collectors.toCollection(ArrayList::new));
    

    或者,同样有效:

    List<Foo> list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-28
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 2011-05-10
      • 2011-12-20
      相关资源
      最近更新 更多