从数组创建 ArrayList

问题描述:

给定一个 Element[] 类型的数组:

Element[] array = {new Element(1), new Element(2), new Element(3)};

如何将此数组转换为 ArrayList 类型的对象?

ArrayList arrayList = ???;

解决方案1:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

new ArrayList<>(Arrays.asList(array));

是的。在(最常见的)您只需要一个列表的情况下,new ArrayList 调用也是不必要的。

@Luron - 只需使用 List list = Arrays.asList(array)

@Calum 和@Pool - 如下亚历克斯米勒的回答中所述,使用 Arrays.asList(array) 而不将其传递给新的 ArrayList 对象将修复列表的大小。使用 ArrayList 的更常见原因之一是能够动态更改其大小,而您的建议会阻止这种情况。

Arrays.asList() 是一个可怕的函数,你永远不应该直接使用它的返回值。它破坏了 List 模板,因此请始终以此处指示的形式使用它,即使它看起来确实是多余的。好答案。

@Adam 请研究 java.util.List 的 javadoc。 add 的合同允许他们抛出 UnsupportedOperationException。 docs.oracle.com/javase/7/docs/api/java/util/… 诚然,从面向对象的角度来看,很多时候您必须知道具体实现才能使用集合并不是很好 - 这是一种实用的设计选择,以保持框架简单。

解决方案2:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

鉴于:

Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };

最简单的答案是:

List list = Arrays.asList(array);

这将正常工作。但有一些注意事项:

从 asList 返回的列表具有固定大小。因此,如果您希望能够在代码的返回列表中添加或删除元素,您需要将其包装在一个新的 ArrayList 中。否则你会得到一个 UnsupportedOperationException。从 asList() 返回的列表由原始数组支持。如果修改原始数组,列表也会被修改。这可能令人惊讶。

Arrays.asList() 只是通过包装现有数组来创建一个 ArrayList,因此它是 O(1)。

包装在新的 ArrayList() 中将导致固定大小列表的所有元素被迭代并添加到新的 ArrayList 中,因此 O(n) 也是如此。

澄清一下,Arrays.asList() 创建了一个 java.util.Arrays.ArrayList(java.util.Arrays 中的静态嵌套类),而不是 java.util.ArrayList。

解决方案3:

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求

(旧线程,但只有 2 美分,因为没有提到番石榴或其他库和其他一些细节)

如果可以,请使用番石榴

值得指出的是 Guava 方式,它极大地简化了这些恶作剧:

用法

对于不可变列表

使用 ImmutableList 类及其 of() 和 copyOf() 工厂方法(元素不能为空):

List il = ImmutableList.of("string", "elements");  // from varargs
List il = ImmutableList.copyOf(aStringArray);      // from array

对于可变列表

使用 Lists 类及其 newArrayList() 工厂方法:

List l1 = Lists.newArrayList(anotherListOrCollection);    // from collection
List l2 = Lists.newArrayList(aStringArray);               // from array
List l3 = Lists.newArrayList("or", "string", "elements"); // from varargs

另请注意其他类中其他数据结构的类似方法,例如 Sets。

为什么是番石榴?

主要的吸引力可能是减少由于类型安全泛型导致的混乱,因为使用 Guava factory methods 允许在大多数时间推断类型。然而,自从 Java 7 与新的菱形运算符一起出现以来,这个论点就不那么成立了。

但这不是唯一的原因(Java 7 还不是无处不在):速记语法也非常方便,并且方法初始化器(如上所示)允许编写更具表现力的代码。您可以在一个 Guava 调用中执行当前 Java 集合需要 2 的操作。

如果你不能…

对于不可变列表

使用 JDK 的 Arrays 类及其 asList() 工厂方法,用 Collections.unmodifiableList() 包装:

List l1 = Collections.unmodifiableList(Arrays.asList(anArrayOfElements));
List l2 = Collections.unmodifiableList(Arrays.asList("element1", "element2"));

请注意,asList() 的返回类型是使用具体 ArrayList 实现的 List,但 它不是 java.util.ArrayList。它是一种内部类型,它模拟 ArrayList 但实际上直接引用传递的数组并使其“写入”(修改反映在数组中)。

它通过简单地扩展 AbstractList 来禁止通过某些 List API 方法进行修改(因此,不支持添加或删除元素),但它允许调用 set() 来覆盖元素。因此,这个列表并不是真正不可变的,对 asList() 的调用应该用 Collections.unmodifiableList() 包装。

如果您需要可变列表,请参阅下一步。

对于可变列表

与上面相同,但用实际的 java.util.ArrayList 包裹:

List l1  = new ArrayList(Arrays.asList(array));    // Java 1.5 to 1.6
List l1b = new ArrayList<>(Arrays.asList(array));          // Java 1.7+
List l2  = new ArrayList(Arrays.asList("a", "b")); // Java 1.5 to 1.6
List l2b = new ArrayList<>(Arrays.asList("a", "b"));       // Java 1.7+

出于教育目的:良好的手动方式

// for Java 1.5+
static  List arrayToList(final T[] array) {
  final List l = new ArrayList(array.length);

  for (final T s : array) {
    l.add(s);
  }
  return (l);
}

// for Java < 1.5 (no generics, no compile-time type-safety, boo!)
static List arrayToList(final Object[] array) {
  final List l = new ArrayList(array.length);

  for (int i = 0; i < array.length; i++) {
    l.add(array[i]);
  }
  return (l);
}

+1 但请注意,Arrays.asList 返回的 List 是可变的,因为您仍然可以 set 元素 - 它只是不可调整大小。对于没有 Guava 的不可变列表,您可能会提到 Collections.unmodifiableList。

解决方案4:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

由于这个问题已经很老了,令我惊讶的是,还没有人提出最简单的形式:

List arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));

从 Java 5 开始,Arrays.asList() 采用可变参数,您不必显式构造数组。

特别是,List a = Arrays.asList("first","second","third")

解决方案5:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

new ArrayList(Arrays.asList(myArray));

确保 myArray 与 T 的类型相同。例如,如果您尝试从 int 数组创建 List,则会出现编译器错误。

解决方案6:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

另一种方式(虽然在性能方面基本上等同于 new ArrayList(Arrays.asList(array)) 解决方案:

Collections.addAll(arraylist, array);

解决方案7:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

爪哇 9

在 Java 9 中,您可以使用 List.of 静态工厂方法来创建 List 文字。类似于以下内容:

List elements = List.of(new Element(1), new Element(2), new Element(3));

这将返回一个包含三个元素的 immutable 列表。如果您想要一个 mutable 列表,请将该列表传递给 ArrayList 构造函数:

new ArrayList<>(List.of(// elements vararg))

JEP 269:集合的便利工厂方法

JEP 269 为 Java Collections API 提供了一些便利的工厂方法。这些不可变的静态工厂方法内置于 Java 9 及更高版本的 List、Set 和 Map 接口中。

List.of() 不会按照原始问题中的要求返回 java.util.ArrayList 的实例。因此,只有第二个选项是有效的答案。

解决方案8:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

您可能只需要一个列表,而不是一个 ArrayList。在这种情况下,您可以这样做:

List arraylist = Arrays.asList(array);

这将由原始输入数组支持,这就是您(可能)想要将其包装在新的 ArrayList 中的原因。

小心这个解决方案。如果你看,Arrays 不会返回一个真正的 java.util.ArrayList。它返回一个实现所需方法的内部类,但您不能更改列表中的成员。它只是一个数组的包装器。

您可以将 List 项目转换为 ArrayList

@Mikezx6r:小更正:这是一个固定大小的列表。您可以更改列表的元素(set 方法),但不能更改列表的大小(不是 add 或 remove 元素)!

是的,但需要注意的是,这取决于您要对列表执行的操作。值得注意的是,如果 OP 只是想遍历元素,则根本不需要转换数组。

解决方案9:

huntsbot.com – 高效赚钱,自由工作

另一个更新,即将于 2014 年结束,您也可以使用 Java 8:

ArrayList arrayList = Stream.of(myArray).collect(Collectors.toCollection(ArrayList::new));

如果这可能只是一个 List,则会保存一些字符

List list = Stream.of(myArray).collect(Collectors.toList());

最好不要依赖于实现,但 Collectors.toList() 实际上会返回一个 ArrayList。

错误使用 Stream.of(...);这将创建一个元素流。改用 Arrays.stream

我不这么认为,这两个选项是有效的,但 Arrays.stream 稍微“更好”,因为您可以使用带有“start”、“end”参数的重载方法以固定大小创建它。另请参阅:stackoverflow.com/a/27888447/2619091

解决方案10:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

如果您使用:

new ArrayList(Arrays.asList(myArray));

您可以创建并填写两个列表!填充两次大列表正是您不想做的,因为每次需要扩展容量时它都会创建另一个 Object[] 数组。

幸运的是,JDK 实现速度很快,Arrays.asList(a[]) 做得很好。它创建一种名为 Arrays.ArrayList 的 ArrayList,其中 Object[] 数据直接指向该数组。

// in Arrays
@SafeVarargs
public static  List asList(T... a) {
    return new ArrayList<>(a);
}
//still in Arrays, creating a private unseen class
private static class ArrayList

    private final E[] a;    
    ArrayList(E[] array) {
        a = array; // you point to the previous array
    }
    ....
}

危险的一面是,如果你改变了初始数组,你就改变了 List !你确定你想要那个吗?可能是可能不是。

如果没有,最容易理解的方法是这样做:

ArrayList list = new ArrayList(myArray.length); // you know the initial capacity
for (Element element : myArray) {
    list.add(element);
}

或者如@glglgl 所说,您可以使用以下命令创建另一个独立的 ArrayList:

new ArrayList(Arrays.asList(myArray));

我喜欢使用 Collections、Arrays 或 Guava。但如果它不合适,或者你没有感觉,那就写另一条不雅的行来代替。

我看不出答案末尾的循环与您不鼓励使用的 new ArrayList(Arrays.asList(myArray)); 部分之间的根本区别。两者的作用完全相同,并且具有相同的复杂性。

Collections 在数组的开头创建一个指针。我的循环创建了许多指针:每个数组成员一个。因此,如果原始数组发生变化,我的指针仍然指向以前的值。

new ArrayList(Arrays.asList(myArray)); 做同样的事情,它将 asList 复制到 ArrayList...

解决方案11:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

在 Java 9 中,您可以使用:

List list = List.of("Hello", "World", "from", "Java");
List list = List.of(1, 2, 3, 4, 5);

请注意,这不是一个 ArrayList,因为它被明确要求。

原文链接:https://www.huntsbot.com/qa/07dL/create-arraylist-from-array?lang=zh_CN

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值