在Java中将数组转换为列表

Ale*_*dru 957 java arrays list data-conversion

如何将数组转换为Java中的列表?

我使用Arrays.asList()但行为(和签名)以某种方式从Java SE 1.4.2(现在存档中的文档)更改为8,我在网上找到的大多数片段使用1.4.2行为.

例如:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
Run Code Online (Sandbox Code Playgroud)
  • 在1.4.2上返回一个包含元素1,2,3的列表
  • 在1.5.0+上返回包含阵列垃圾邮件的列表

在许多情况下,它应该很容易被发现,但有时它可能会被忽视:

Assert.assertTrue(Arrays.asList(spam).indexOf(4) == -1);
Run Code Online (Sandbox Code Playgroud)

Joe*_*ley 1363

在您的示例中,这是因为您不能拥有基本类型的List.换句话说,List<int>是不可能的.

但是,您可以List<Integer>使用Integer包装int基元的类.List使用Arrays.asList实用程序方法将数组转换为a .

Integer[] spam = new Integer[] { 1, 2, 3 };
List<Integer> list = Arrays.asList(spam);
Run Code Online (Sandbox Code Playgroud)

请参阅IdeOne.com上的代码.

  • 甚至更简单:Arrays.asList(1,2,3); (104认同)
  • 怎么知道不创建`List <Integer []>`? (41认同)
  • Java 5+失败. (24认同)
  • @ThomasAhle它不创建List <Integer []>它创建一个List <Integer>对象.如果你想要类型安全,你写:Arrays.<Integer> asList(spam); (5认同)
  • @ThomasAhle这是一个很好的问题.猜测它只是java编译器中的一个规则.例如,以下代码返回List <Integer []>`Integer [] integerArray1 = {1}; Integer [] integerArray2 = {2}; List <Integer []> integerArrays = Arrays.asList(integerArray1,integerArray2); ` (5认同)
  • @ThomasAhle您可以传入Arrays.asList 0个或更多元素,以逗号分隔的格式或数组格式传递任意值。结果将始终相同-您指定的元素列表。这是因为方法签名:public static &lt;T&gt; List &lt;T&gt; asList(T ... a)。在这里,您可以阅读有关varargs的更多信息http://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html#varargs (2认同)
  • @pedrambashiri 它不适用于原始数组,例如 `int[]`、`long[]`、`double[]` ,仅适用于 `Integer[]`、`Long[]`、`Double[]` 。 .. (2认同)
  • 请记住,Arrays.asList() 返回一个 Arrays$ArrayList,它是固定大小的列表并保持对原始数组的引用。它提供了一个 api 来通过 List 的方法处理实际数组。 (2认同)
  • 当你向它发送一个原始数组时,会发生什么,它会将该原始数组解释为第一个可变参数。发生这种情况是因为“asList”需要对象,因为它和“List”使用需要对象而不是基元的通用类型。由于“int”不是对象,但“int[]”是对象,因此它对它的解释与发送“Integer[]”不同,后者是包含“Integer”对象的对象数组。因此,在第二种情况下,它将数组中的“Integers”视为可变参数项,而不是将“Integer[]”视为可变参数项本身。 (2认同)
  • @theferrit32 您可以创建一个 `List&lt;Integer[]&gt; list = Arrays.&lt;Integer[]&gt;asList(spam);` 逻辑已在 JLS §15.12.2 中指定。正如您所说,原因是可变参数是数组参数的语法糖,因此必须与在匹配数组中传递的代码保持向后兼容。 (2认同)

Ibr*_*ief 149

在Java 8中,您可以使用流:

int[] spam = new int[] { 1, 2, 3 };
Arrays.stream(spam)
      .boxed()
      .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • 在 Java 16 中简化为 Arrays.stream(spam).boxed().toList(); (4认同)

Rom*_*nko 132

谈到转换方式,这取决于你为什么需要你的List.如果您需要它只是为了读取数据.好的,你走了:

Integer[] values = { 1, 3, 7 };
List<Integer> list = Arrays.asList(values);
Run Code Online (Sandbox Code Playgroud)

但是如果你做这样的事情:

list.add(1);
Run Code Online (Sandbox Code Playgroud)

你得到java.lang.UnsupportedOperationException.所以在某些情况下你甚至需要这个:

Integer[] values = { 1, 3, 7 };
List<Integer> list = new ArrayList<Integer>(Arrays.asList(values));
Run Code Online (Sandbox Code Playgroud)

第一种方法实际上不转换数组,但"代表"它就像一个List.但是数组是所有属性的固定数量的元素.请注意,您需要在构建时指定类型ArrayList.


Pét*_*rök 122

问题是varargs是在Java5中引入的,不幸的是,Arrays.asList()vararg版本也超载了.因此Arrays.asList(spam),Java5编译器将其理解为int数组的vararg参数.

在Effective Java 2nd Ed.,第7章,第42项中更详细地解释了这个问题.

  • 我理解发生了什么,但不知道为什么没有记录.我正在寻找一种替代解决方案,而无需重新实现车轮. (3认同)
  • @UsmanIsmail从Java 8开始,我们可以使用流进行此转换.请参阅我的回答[下方](http://stackoverflow.com/a/30281879/752918). (2认同)

i_a*_*ero 94

这似乎不太晚,但这是我的两分钱.我们不能List<int>因为int是基本类型,所以我们只能有List<Integer>.

Java 8(int数组)

int[] ints = new int[] {1,2,3,4,5};
List<Integer> list11 =Arrays.stream(ints).boxed().collect(Collectors.toList()); 
Run Code Online (Sandbox Code Playgroud)

Java 8及以下版本(整数数组)

Integer[] integers = new Integer[] {1,2,3,4,5};
List<Integer> list21 =  Arrays.asList(integers); // returns a fixed-size list backed by the specified array.
List<Integer> list22 = new ArrayList<>(Arrays.asList(integers)); // good
List<Integer> list23 = Arrays.stream(integers).collect(Collectors.toList()); //Java 8 only
Run Code Online (Sandbox Code Playgroud)

需要ArrayList而不是List吗?

如果我们希望有一个具体的实施ListArrayList然后我们可以使用toCollection如下:

ArrayList<Integer> list24 = Arrays.stream(integers)
                          .collect(Collectors.toCollection(ArrayList::new));
Run Code Online (Sandbox Code Playgroud)

为什么list21不能进行结构修改?

当我们使用Arrays.asList返回列表的大小是固定的,因为返回的列表不是java.util.ArrayList,而是在里面定义的私有静态类java.util.Arrays.因此,如果我们在返回的列表中添加或删除元素,UnsupportedOperationException则会抛出一个元素.所以我们应该list22在我们想要修改列表时使用.如果我们有Java8,那么我们也可以使用list23.

要清楚list21可以在我们可以调用的意义上进行修改,list21.set(index,element)但是这个列表可能没有结构修改,即无法在列表中添加或删除元素.您也可以查看此问题.


如果我们想要一个不可变列表,那么我们可以将其包装为:

List<Integer> list 22 = Collections.unmodifiableList(Arrays.asList(integers));
Run Code Online (Sandbox Code Playgroud)

另一点需要注意的是,该方法Collections.unmodifiableList返回指定列表的不可修改视图.不可修改的视图集合是一个不可修改的集合,也是一个支持集合的视图.请注意,可能仍然可以对支持集合进行更改,如果它们发生,则通过不可修改的视图可以看到它们.

我们可以在Java 10中拥有一个真正不可变的列表.

Java 10(真正不变的列表)有两种方式:

  1. List.copyOf(Arrays.asList(integers))
  2. Arrays.stream(integers).collect(Collectors.toUnmodifiableList());

另请查看我的答案以获取更多信息.


Ste*_*man 10

我最近不得不将数组转换为List.稍后程序过滤了试图删除数据的列表.使用Arrays.asList(array)函数时,可以创建固定大小的集合:既不能添加也不能删除.这个条目比我能更好地解释了这个问题:为什么在尝试从List中删除元素时会得到UnsupportedOperationException?.

最后,我不得不进行"手动"转换:

    List<ListItem> items = new ArrayList<ListItem>();
    for (ListItem item: itemsArray) {
        items.add(item);
    }
Run Code Online (Sandbox Code Playgroud)

我想我可以使用List.addAll(items)操作添加从数组到列表的转换.

  • `new ArrayList <ListItem>(Arrays.asList(itemsArray))`会相同 (11认同)
  • 检查工具可能会在此处显示警告,您已将其命名为原因.无需手动复制元素,而是使用`Collections.addAll(items,itemsArray)`. (2认同)

小智 9

更短:

List<Integer> list = Arrays.asList(1, 2, 3, 4);
Run Code Online (Sandbox Code Playgroud)


Pie*_*tto 7

在 Java 9 中,您拥有通过新的便利工厂方法使用不可变列表的更优雅的解决方案List.of

List<String> immutableList = List.of("one","two","three");
Run Code Online (Sandbox Code Playgroud)

(无耻地从这里复制)


ala*_*ter 6

如果您使用 apache commons-lang,则另一种解决方法:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(ArrayUtils.toObject(spam));
Run Code Online (Sandbox Code Playgroud)

ArrayUtils.toObject转换int[]Integer[]


Bhu*_*han 6

单线:

List<Integer> list = Arrays.asList(new Integer[] {1, 2, 3, 4});
Run Code Online (Sandbox Code Playgroud)


nyb*_*bon 6

如果你的目标是 Java 8(或更高版本),你可以试试这个:

int[] numbers = new int[] {1, 2, 3, 4};
List<Integer> integers = Arrays.stream(numbers)
                        .boxed().collect(Collectors.<Integer>toList());
Run Code Online (Sandbox Code Playgroud)

笔记:

注意Collectors.<Integer>toList(),这种通用方法可以帮助您避免错误“类型不匹配:无法转换List<Object>List<Integer>”。


Min*_*ang 6

使用数组

这是将数组转换为的最简单方法List.但是,如果您尝试添加新元素或从列表中删除现有元素,UnsupportedOperationException则会抛出一个元素.

Integer[] existingArray = {1, 2, 3};
List<Integer> list1 = Arrays.asList(existingArray);
List<Integer> list2 = Arrays.asList(1, 2, 3);

// WARNING:
list2.add(1);     // Unsupported operation!
list2.remove(1);  // Unsupported operation!
Run Code Online (Sandbox Code Playgroud)

使用ArrayList或其他列表实现

您可以使用for循环将数组的所有元素添加到List实现中,例如ArrayList:

List<Integer> list = new ArrayList<>();
for (int i : new int[]{1, 2, 3}) {
  list.add(i);
}
Run Code Online (Sandbox Code Playgroud)

在Java 8中使用Stream API

您可以将数组转换为流,然后使用不同的收集器收集流:Java 8中的默认收集器在ArrayList屏幕后面使用,但您也可以强制执行首选实现.

List<Integer> list1, list2, list3;
list1 = Stream.of(1, 2, 3).collect(Collectors.toList());
list2 = Stream.of(1, 2, 3).collect(Collectors.toCollection(ArrayList::new));
list3 = Stream.of(1, 2, 3).collect(Collectors.toCollection(LinkedList::new));
Run Code Online (Sandbox Code Playgroud)

也可以看看:


小智 5

你必须转换成数组

Arrays.asList((Object[]) array)
Run Code Online (Sandbox Code Playgroud)

  • java:不兼容的类型:int[] 无法转换为 java.lang.Object[] (3认同)