我有一个初始化的数组,如下所示:
我想将这个数组转换成arraylist类的对象。
1
| ArrayList<Element> arraylist = ???; |
- 在Java9> >列表< String >列表=列表中("hello"、"Word"、"of"、"java");
- @Marek这个答案是错误的,因为它不会返回ArrayList。海报特别要求这样做。
- 我认为他没有使用列表界面,因为这是最佳实践。但是如果你想要的是新的AARAYLIST< <(Hello)、"Word"、"On"、"Java"的列表。
- 关键不在于使用接口,关键是在解决方案中,返回的列表是不可修改的。这可能是一个更大的问题,也是他为什么要一个阵列列表的原因。
1
| new ArrayList <>(Arrays. asList(array )) |
- 是的。在(最常见的)情况下,您只需要一个列表,new ArrayList调用也是不必要的。
- @Luron-只需使用List list = Arrays.asList(array)
- @calum和@pool——如下面Alex Miller的回答所述,使用Arrays.asList(array),而不将其传递到新的ArrayList对象中,将固定列表的大小。使用ArrayList的一个更常见的原因是能够动态地更改其大小,您的建议可以防止这种情况发生。
- 我想指出的是,如果您想用迭代器执行可变(如remove)操作,那么新的arraylist部分是必需的。
- arrays.aslist()是一个糟糕的函数,您不应该只使用它的返回值。它会破坏列表模板,因此始终以此处指示的格式使用它,即使它看起来是多余的。好答案。
- 警告:我刚刚遇到Java 6的错误行为:当元素是一个原始元素(例如数组是int [])时,ASLIST创建列表INT[] >。
- @当您想要一个由特定数组支持的列表时,AdamArrays.asList()是一个非常有用的方法。例如,Collections.shuffle(Arrays.asList(myarray))对原始数组进行洗牌。
- @lbalazscs是真的,但我会说这非常接近黑客(即使shuffle方法是打算这样使用的),因为你基本上是在欺骗它,让它认为它是在处理一个列表,而不是。方便,但我还是说这是一个可怕的功能。我的论点基本上是aslist()方法有误导性,因为它看起来像返回给定数组的列表表示,而实际上它只返回部分实现的列表表示。
- @Adam请学习javadoc for java.util.list。添加合同允许他们抛出一个不支持的操作异常。DOCS.Oracle .COM/JavaSe/ 7 /DOCS/API/Java/UTL/HelLIP;诚然,从面向对象的角度看,很多时候您必须知道具体的实现以使用集合——这是一个务实的设计选择,以保持框架简单。
- @阿卡迪,当a是int[]时,Arrays.asList(a).get(0) == a并不是一个错误。这是因为asList(Object...)varargs是如何解决的。int[]类型的对象是Object,而不是Object[],因此Arrays.asList正通过一个元素为Object的数组:int的数组。
- @安德烈,我明白为什么会这样。只不过是为了我打破了德威姆。
- 当数组类型为int[]且等效用例为so:List intList = new ArrayList(Arrays.asList(intArray));时,这不会编译。
- array.aslist(array).remove(key)将抛出:Exception in thread"main" java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161) at ... -dunno AbstractList是如何进入的,但在调用remove时不希望出现这种情况。
- 对于数组是像int[]这样的基元类型的情况,请参阅以下问题和答案:stackoverflow.com/questions/1073919/&hellip;
- 从旁注来看,List list = new ArrayList<>(Arrays.asList(array));就足够了。菱形运算符将为您进行类型推断。
- @可能是因为Arrays.asList返回的列表属于继承AbstractList的类,不实现remove(这是因为不能从数组中删除内容)
- 这对于Java 1.8不起作用。在Java 1.8中,EDCOX1(0)将创建一个列表,其唯一元素是EDCOX1×1。结果列表不包含array的元素。
- 我刚刚发现(至少对于开放式JDK)是数组。aslist(array)在数组周围创建了一个轻量级的列表包装器,但是相应的toarray调用创建了一个新的数组副本。调用new arraylist(collection)调用此to array方法,然后创建另一个防御副本,这意味着另外一个数组分配。您可以通过在guava中使用lists.new arraylist或创建新的arraylist(array.length),然后复制所有元素来避免这些问题。
- 使用Java 9,您应该使用EDCOX1(3),它提供了一个不可变的列表(内部类EDCOX1(4)的实例)。如果需要可修改的列表,可以使用new ArrayList<>(List.of(array))。见表
鉴于:
最简单的答案是:
1
| List <Element > list = Arrays. asList(array ); |
这样就行了。但需要注意的是:
从aslist返回的列表大小固定。因此,如果希望能够在代码中添加或删除返回列表中的元素,则需要将其包装在新的ArrayList中。否则你会得到一个UnsupportedOperationException。
从asList()返回的列表由原始数组支持。如果修改原始数组,列表也将被修改。这可能令人惊讶。
- 两种操作的时间复杂性是什么?我的意思是使用和不使用显式数组列表结构。
- arrays.aslist()只是通过包装现有数组来创建arraylist,因此它是O(1)。
- 包装一个新的arraylist()将导致固定大小列表的所有元素被迭代并添加到新的arraylist中,o(n)也是如此。
- aslist()返回的list的实现没有实现list的几个方法(如add()、remove()、clear()等…),这解释了unsupportedOperationException。绝对是个警告…
- 当问题问到"ArrayList类的一个对象"时,我认为假设它所指的类是java.util.ArrayList是合理的。arrays.aslist实际上返回一个java.util.Arrays.ArrayList,而不是另一个类instanceof。因此,第三个警告是,如果您试图在需要上述内容的环境中使用它,它将不起作用。
(旧线,但只有2美分,因为没有提到番石榴或其他伦敦银行同业拆借利率和其他一些细节)
如果可以的话,用番石榴
有必要指出番石榴的方式,这大大简化了这些恶作剧:
用法对于不可变列表
使用ImmutableList类及其of()和copyOf()工厂方法(元素不能为空):
1 2
| List<String> il = ImmutableList.of("string","elements"); // from varargs
List<String> il = ImmutableList.copyOf(aStringArray); // from array |
对于可变列表
使用Lists类及其newArrayList()工厂方法:
1 2 3
| List<String> l1 = Lists.newArrayList(anotherListOrCollection); // from collection
List<String> l2 = Lists.newArrayList(aStringArray); // from array
List<String> l3 = Lists.newArrayList("or","string","elements"); // from varargs |
还请注意其他类中其他数据结构的类似方法,例如在Sets中。
为什么番石榴?
主要的吸引力可能是减少由于类型安全的泛型导致的混乱,因为使用guava工厂方法可以在大多数时间推断类型。然而,自从Java 7到达新的钻石操作符之后,这个论点就没有那么多了。
但这并不是唯一的原因(Java 7并不是无处不在):速记语法也是非常方便的,并且方法初始化器,如上所述,允许编写更富表现力的代码。在一个番石榴调用中,使用当前Java集合占2。
如果你不能…对于不可变列表
使用JDK的Arrays类及其asList()工厂方法,用Collections.unmodifiableList()包装:
注意,asList()的返回类型是使用具体的ArrayList实现的List,但不是java.util.ArrayList。它是一个内部类型,它模拟ArrayList,但实际上直接引用传递的数组并使其"写入"(修改反映在数组中)。
它通过简单地扩展AbstractList来禁止通过ListAPI的某些方法进行修改(因此,不支持添加或删除元素),但是它允许调用set()来重写元素。因此,这个列表并不是真正不变的,对asList()的调用应该用Collections.unmodifiableList()包装。
如果需要可变列表,请参见下一步。
对于可变列表
同上,但用实际的java.util.ArrayList包裹:
1 2 3 4
| List <String > l1 = new ArrayList <String >(Arrays. asList(array )); // Java 1.5 to 1.6
List <String > l1b = new ArrayList <>(Arrays. asList(array )); // Java 1.7+
List <String > l2 = new ArrayList <String >(Arrays. asList("a", "b")); // Java 1.5 to 1.6
List <String > l2b = new ArrayList <>(Arrays. asList("a", "b")); // Java 1.7+ |
出于教育目的:良好的"手动"方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // for Java 1.5+
static <T > List <T > arrayToList (final T [] array ) {
final List <T > l = new ArrayList <T >(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。
- 在你的章节中,为了教育目的:好的OL的手工方式,你的EDCOX1对Java 1.5 + 18是不正确的。您正在显示EDOCX1的列表(19),并尝试从给定的数组中检索字符串,而不是使用通用参数类型T。除此之外,很好的答案,而且+1是唯一包括手动方式的答案。
由于这个问题已经很老了,我惊讶的是还没有人提出最简单的形式:
至于Java 5,EDCOX1 OR 7表示取一个VARARGS参数,而不必显式构造数组。
- 尤其是List a = Arrays.asList("first","second","third")。
1
| new ArrayList <T >(Arrays. asList(myArray )); |
确保myArray与T的类型相同。例如,如果您试图从一个int数组中创建一个List,就会得到一个编译器错误。
另一种方法(虽然本质上等同于new ArrayList(Arrays.asList(array))解决方案的性能:
爪哇9
在Java 9中,可以使用EDCOX1和8的静态工厂方法来创建EDCOX1×4×文字。如下所示:
这将返回包含三个元素的不可变列表。如果需要可变列表,请将该列表传递给arraylist构造函数:
1
| new ArrayList <>(List. of(// elements vararg)) |
jep 269:便利工厂收集方法
JEP 269为Java集合API提供了一些方便的工厂方法。这些不可变的静态工厂方法被构建在EDCOX1、4、EDCOX1、12、EDCX1和13接口9和9中。
你可能只需要一个列表,而不是数组列表。在这种情况下,您可以这样做:
1
| List <Element > arraylist = Arrays. asList(array ); |
- 这将由原始的输入数组支持,这就是为什么您(可能)希望将它包装在一个新的数组列表中。
- 小心这个解决方案。如果你看,数组不会返回一个真正的java.util.arraylist。它返回一个实现所需方法的内部类,但不能更改列表中的memeber。它只是一个数组的包装器。
- 可以将list项强制转换为arraylist
- @小更正:这是一个固定大小的列表。您可以更改列表的元素(set方法),您不能更改列表的大小(不是add或remove元素)!
- 是的,但要注意的是,这取决于你想对列表做什么。不值得注意的是,如果OP只想遍历元素,就不必转换数组。
- @Monksy不,你不能。如前所述,这是一种不同的ArrayList。
- 如果数组元素在Java 8中是基元类型,那么这是不起作用的。有关详细信息,请参阅stackoverflow.com/q/2607289/431698
另一个更新,几乎在2014年底结束,你也可以用Java 8来完成它:
1
| ArrayList <Element > arrayList = Stream. of(myArray ). collect(Collectors. toCollection(ArrayList::new)); |
如果这只是一个List,则会保存几个字符。
1
| List<Element> list = Stream.of(myArray).collect(Collectors.toList()); |
- 最好不要依赖于实现,但Collectors.toList()实际上返回ArrayList。
- 不正确地使用了stream.of(…);这将创建一个元素流。改用array.stream
- 我不这么认为,这两个选项是有效的,但是array.stream稍微"更好",因为您可以使用带有"start"、"end"参数的重载方法以固定大小创建它。另请参见:stackoverflow.com/a/27888447/2619091
如果使用:
1
| new ArrayList <T >(Arrays. asList(myArray )); |
您可以创建并填写两个列表!两次填充一个大列表正是您不想做的,因为它将在每次需要扩展容量时创建另一个Object[]数组。
幸运的是,JDK的实现速度很快,Arrays.asList(a[])也做得很好。它创建一种名为arrays.arraylist的arraylist,对象[]数据直接指向该数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| // in Arrays
@SafeVarargs
public static <T > List <T > asList (T... a) {
return new ArrayList <>(a );
}
//still in Arrays, creating a private unseen class
private static class ArrayList <E >
private final E [] a ;
ArrayList(E [] array ) {
a = array ; // you point to the previous array
}
....
} |
危险的一面是,如果更改初始数组,则会更改列表!你确定要吗?也许是的,也许不是。
如果没有,最容易理解的方法是:
1 2 3 4
| ArrayList <Element > list = new ArrayList <Element >(myArray. length); // you know the initial capacity
for (Element element : myArray ) {
list. add(element );
} |
或者如前面所说的@glglgl,您可以使用以下命令创建另一个独立数组列表:
1
| new ArrayList <T >(Arrays. asList(myArray )); |
我喜欢用Collections、Arrays或guava。但如果它不合适,或者你感觉不到,就写另一行不雅的话。
- 我看不出你在答案末尾的循环和你不愿意使用的new ArrayList(Arrays.asList(myArray));部分之间的根本区别。两者都做得非常相同,并且具有相同的复杂性。
- 集合1在数组的开头创建一个指针。我的循环创建了许多指针:每个数组成员一个。因此,如果原始数组发生变化,那么我的POINER仍然指向以前的值。
- new ArrayList(Arrays.asList(myArray));也一样,它把asList复制到ArrayList上。
在Java 9中,您可以使用:
1 2
| List <String > list = List. of("Hello", "World", "from", "Java");
List <Integer > list = List. of(1, 2, 3, 4, 5); |
- 注意,这不是一个数组列表,正如它被明确要求的那样。
根据问题,使用Java 1.7的答案是:
1
| ArrayList <Element > arraylist = new ArrayList <Element >(Arrays. <Element >asList (array )); |
但是最好始终使用接口:
1
| List <Element > arraylist = Arrays. <Element >asList (array ); |
1 2 3 4
| // Guava
import com.google.common.collect.ListsLists
...
List<String> list = Lists.newArrayList(aStringArray); |
您可以使用不同的方法转换
List list = Arrays.asList(array);
List list = new ArrayList();
Collections.addAll(list, array);
Arraylist list = new Arraylist();
list.addAll(Arrays.asList(array));
有关详细信息,请参阅http://javarevisited.blogspot.in/2011/06/converting-array-to-arraylist-in-java.html。
正如所有人所说的那样
1
| new ArrayList <>(Arrays. asList("1", "2", "3", "4")); |
创建数组的最新方法是ObservableArrays
ObservableList:一个列表,允许侦听器在更改发生时跟踪更改。
对于Java SE,您可以尝试
这是根据甲骨文文件
observableArrayList()
Creates a new empty observable list that is backed by an arraylist.
observableArrayList(E... items)
Creates a new observable array list with items added to it.
更新Java 9
在Java 9中也有一点简单:
1
| List <String > list = List. of("element 1", "element 2", "element 3"); |
自Java 8以来,有一种更容易的转换方法:
1 2 3
| public static <T > List <T > fromArray (T [] array ) {
return Arrays. stream(array ). collect(toList ());
} |
您也可以在Java 8中使用流进行处理。
1
| List <Element > elements = Arrays. stream(array ). collect(Collectors. toList()); |
- 对于Java 8,EDCOX1 OR 4将返回EDCOX1 3Ω。但是,在Java上的未来版本中,这可能有所不同。如果您想要特定类型的集合,则使用EDCOX1 OR 8代替您可以指定要创建的集合的确切类型。
如果我们看到Arrays.asList()方法的定义,您会得到如下结果:
1
| public static <T> List<T> asList(T... a) //varargs are of T type. |
所以,您可以这样初始化arraylist:
Note : each new Element(int args) will be treated as Individual Object and can be passed as a var-args.
这个问题可能还有另一个答案。如果您看到java.util.Collections.addAll()方法的声明,您将得到如下结果:
1
| public static <T> boolean addAll(Collection<? super T> c, T... a); |
所以,这段代码也很有用
另一个简单的方法是使用for each循环将数组中的所有元素添加到新的arraylist。
1 2 3 4
| ArrayList <Element > list = new ArrayList <>();
for(Element e : array )
list. add(e ); |
如果数组是基元类型,则给出的答案将不起作用。但由于Java 8,您可以使用:
1 2
| int[] array = new int[5];
Arrays. stream(array ). boxed(). collect(Collectors. toList()); |
我们可以很容易地将数组转换为ArrayList。我们使用收集接口的addAll()方法将内容从一个列表复制到另一个列表。
1 2
| Arraylist arr = new Arraylist ();
arr. addAll(Arrays. asList(asset )); |
- 这比公认的9年前的答案效率低。
- ArrayList的一个构造函数接受? extends Collection参数,使得对addAll的调用是多余的。
即使这个问题有许多完美的书面答案,我还是会添加我的输入。
比如说你有一个Element[] array = { new Element(1), new Element(2), new Element(3) };。
可以通过以下方式创建新的ArrayList
1 2 3 4 5 6 7
| ArrayList <Element > arraylist_1 = new ArrayList <>(Arrays. asList(array ));
ArrayList <Element > arraylist_2 = new ArrayList <>(
Arrays. asList(new Element[] { new Element(1), new Element(2), new Element(3) }));
// Add through a collection
ArrayList <Element > arraylist_3 = new ArrayList <>();
Collections. addAll(arraylist_3, array ); |
他们非常支持ArrayList的所有操作
1 2 3
| arraylist_1. add(new Element(4)); // or remove(): Success
arraylist_2. add(new Element(4)); // or remove(): Success
arraylist_3. add(new Element(4)); // or remove(): Success |
但以下操作只返回ArrayList的列表视图,而不是实际的ArrayList。
1 2 3 4
| // Returns a List view of array and not actual ArrayList
List <Element > listView_1 = (List <Element >) Arrays. asList(array );
List <Element > listView_2 = Arrays. asList(array );
List <Element > listView_3 = Arrays. asList(new Element(1), new Element(2), new Element(3)); |
因此,在尝试执行一些数组列表操作时,它们会出错。
1 2 3
| listView_1. add(new Element(4)); // Error
listView_2. add(new Element(4)); // Error
listView_3. add(new Element(4)); // Error |
关于数组链接的列表表示的更多信息。
使用以下代码将元素数组转换为ArrayList。
您可以在Java 8中这样做,如下所示
1
| ArrayList <Element > list = (ArrayList <Element >)Arrays. stream(array ). collect(Collectors. toList()); |
- 投反对票是因为那个演员看起来很危险。没有指定返回的列表类型实际上是一个arraylist,正如javadoc所说:"对于返回的列表的类型、可变性、可序列化性或线程安全性没有任何保证。"
- 如果你想明确地创建一个数组列表,可以试试这个:ArrayList list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new));。
Another Java8 solution (I may have missed the answer among the large set. If so, my apologies). This creates an ArrayList (as opposed to a List) i.e. one can delete elements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package package org.something.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Junk {
static <T > ArrayList <T > arrToArrayList (T [] arr ){
return Arrays. asList(arr )
. stream()
. collect(Collectors. toCollection(ArrayList::new));
}
public static void main (String[] args ) {
String[] sArr = new String[]{"Hello", "cruel", "world"};
List <String > ret = arrToArrayList (sArr );
// Verify one can remove an item and print list to verify so
ret. remove(1);
ret. stream()
. forEach(System. out::println );
}
} |
输出是…你好世界
最简单的方法是添加以下代码。经过测试。
1 2
| String[] Array1 ={"one", "two", "three"};
ArrayList <String > s1 = new ArrayList <String >(Arrays. asList(Array1 )); |
每个人都已经为你的问题提供了足够好的答案。现在,从所有的建议中,您需要决定哪个适合您的需求。您需要了解两种类型的集合。一个是未修改的集合,另一个是允许您稍后修改对象的集合。
所以,这里我将给出两个用例的简短示例。
不可变集合创建::当您不想在创建后修改集合对象时
List elementList = Arrays.asList(array)
可变集合创建::当您可能希望在创建后修改创建的集合对象时。
List elementList = new ArrayList(Arrays.asList(array));
- listelement list=array.as list(array)在原始数组上创建一个包装器,使原始数组可用作列表。因此,将创建一个包装对象,而不会从原始数组中复制任何内容。因此,不允许执行诸如添加或删除元素之类的操作。
- 请注意,您的"不可变集合"不是真正不可变的-由Arrays.asList返回的List只是原始数组的包装,允许通过get和set访问和修改单个项。您可能应该澄清您的意思是"不添加或删除元素",而不是"不可变",这意味着根本不更改。
您可以使用cactoos(我是开发人员之一)创建一个arraylist:
1 2 3
| List<String> names = new StickyList<>(
"Scott Fitzgerald","Fyodor Dostoyevsky"
); |
不能保证对象实际上是arraylist类。如果您需要担保,请执行以下操作:
1 2 3 4 5
| ArrayList<String> list = new ArrayList<>(
new StickyList<>(
"Scott Fitzgerald","Fyodor Dostoyevsky"
)
); |
- 我尊重你的工作。但是作为Java的新手,EDCOX1 10和它的其余部分(ARARYLIST等)已经太难处理了。为什么你想让我承受更多的痛苦:-(
这是一个明确的方法
1
| ArrayList <Element > arraylist = new ArrayList <>(Arrays. asList(array )) |
使用下面的代码
如果您的目标是在运行时生成一个固定列表,那么还有另一个选项,它既简单又有效:
1 2 3 4 5 6 7 8 9 10
| static final ArrayList <Element > myList = generateMyList ();
private static ArrayList <Element > generateMyList () {
final ArrayList <Element > result = new ArrayList <>();
result. add(new Element(1));
result. add(new Element(2));
result. add(new Element(3));
result. add(new Element(4));
return result ;
} |
使用此模式的好处是,列表是非常直观地一次性生成的,因此即使使用大列表或复杂的初始化也很容易修改,而另一方面,在程序的每次实际运行中始终包含相同的元素(当然,除非您在以后更改它)。
- 这并不能回答最初的问题。OP已经在一个容器中包含了元素,我们可以假设它包含随机内容。这种方法依赖于每次运行此代码时需要完全相同元素的列表。此外,过度使用静态关键字是不好的实践,而且在实践中还有许多其他的方法可以做到这一点,其中涉及的样板代码较少。