将数组转换为Java中的列表


1027

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

我使用了,Arrays.asList()但是行为(和签名)从Java SE 1.4.2(现在已存档的文档)以某种方式改变为8,而我在网络上发现的大多数代码片段都使用1.4.2行为。

例如:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
  • 在1.4.2上返回包含元素1,2,3的列表
  • 在1.5.0+上返回包含数组垃圾邮件的列表

在许多情况下,它应该很容易检测到,但是有时它可能会被忽略而不会被注意到:

Assert.assertTrue(Arrays.asList(spam).indexOf(4) == -1);

20
我觉得你的例子被打破:Arrays.asList(new int[] { 1, 2, 3 }); 绝对没有用Java 1.4.2编译,因为int[]不是一个Object[]
Joachim Sauer 2010年

1
哦,你可能是对的。发布之前,我没有Java 1.4.2编译器来测试我的示例。现在,经过您的评论和乔的回答,一切都变得更加有意义了。
亚历山德鲁

1
我认为自动装箱将涵盖从原始到包装Integer类的转换。您可以先自己进行演员表转换,然后上面的代码Arrays.asList应该可以工作。
马之声

2
Java 8的Stream.boxed()将负责自动装箱,可用于此目的。请参阅下面的答案。
Ibrahim Arief 2015年

Answers:


1430

在您的示例中,这是因为您没有原始类型的列表。换句话说,这List<int>是不可能的。

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

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

看到此代码在IdeOne.com上实时运行


112
或更简单:Arrays.asList(1、2、3);
香港

45
它怎么知道不创建一个List<Integer[]>
Thomas Ahle 2014年

25
在Java 5+中失败。
djechlin

5
@ThomasAhle它不会创建List <Integer []>,而是创建List <Integer>对象。如果要确保类型安全,请编写:Arrays。<Integer> asList(spam);
user1712376 2014年

6
@ThomasAhle这是一个很好的问题。猜测这只是Java编译器中的一条规则。例如,以下代码返回List <Integer []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
Simon

167

在Java 8中,可以使用流:

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

很好,但不适用于boolean[]。我猜那是因为制作一个一样容易Boolean[]。那可能是一个更好的解决方案。无论如何,这是一个有趣的怪癖。
GlenPeterson

138

说到转换方式,取决于您为什么需要List。如果您只需要读取数据。好,到这里:

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

但是,如果您执行以下操作:

list.add(1);

你懂了java.lang.UnsupportedOperationException。因此,在某些情况下,您甚至需要这样做:

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

第一种方法实际上并不转换数组,而是像一样“表示”它List。但是数组具有其所有属性,例如固定数量的元素,处于底层。请注意,在构造时需要指定类型ArrayList


1
“不变性”使我困惑了片刻。您显然可以更改数组的值。但是,您无法更改其大小。
Tim Pohlmann

125

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

此问题在有效的Java第二版,第7章,项目42中有更详细的说明。


4
我了解发生了什么,但不了解为什么没有记录。我正在寻找一种替代解决方案,而无需重新安装轮子。
亚历山德鲁

2
@UsmanIsmail从Java 8开始,我们可以使用流进行此转换。请参阅下面的答案。
Ibrahim Arief 2015年

109

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

Java 8(整数数组)

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

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

需要ArrayList而不是List吗?

如果我们想要List例如的特定实现,ArrayList那么我们可以使用toCollection

ArrayList<Integer> list24 = Arrays.stream(integers)
                          .collect(Collectors.toCollection(ArrayList::new));

为什么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));

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

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

真正不可变的清单

Java 9:

String[] objects = {"Apple", "Ball", "Cat"};
List<String> objectList = List.of(objects);

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

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

还要检查我的答案以获取更多信息。


@BasilBourque我的意思是无法通过添加/删除来修改列表的结构,但可以更改元素。
akhil_mittal '19

确实,我尝试了一些代码,并确认调用List::addList::remove失败,并返回了一个列表Arrays.asList。该方法的JavaDoc编写得很差,目前还不清楚。在我的三读中,我假设短语“固定大小”的意思是说不能添加或删除元素。
罗勒·布尔克


11

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

最后,我必须进行“手动”转换:

    List<ListItem> items = new ArrayList<ListItem>();
    for (ListItem item: itemsArray) {
        items.add(item);
    }

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


11
new ArrayList<ListItem>(Arrays.asList(itemsArray))也会一样
Marco13

1
@BradyZhu:上面给出的答案不能解决固定大小数组的问题,但是您在这里基本上是说RTFM,这总是不好的形式。请详细说明答案有什么问题或不要评论。
史蒂夫·盖尔曼

2
检查工具可能会在此处显示警告,并且您已列出了原因。无需手动复制元素,Collections.addAll(items, itemsArray)而是使用。
Darek Kay 2015年

只需打这个例外。恐怕Marco13的答案应该是正确的答案。我可能需要遍历全年代码才能修复所有“ asList”异常。

7

使用数组

这是将数组转换为的最简单方法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!

使用ArrayList或其他列表实现

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

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

在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));

也可以看看:


6

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

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

ArrayUtils.toObject转换int[]Integer[]



5

单线:

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


5

如果您以Java 8(或更高版本)为目标,则可以尝试以下操作:

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

注意:

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


4
  1. 使用番石榴:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = Lists.newArrayList(sourceArray);
  2. 使用Apache Commons Collections:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = new ArrayList<>(6);
    CollectionUtils.addAll(list, array);

3

如果这有帮助:我遇到了同样的问题,只是编写了一个通用函数,该函数接受一个数组并返回具有相同内容的相同类型的ArrayList:

public static <T> ArrayList<T> ArrayToArrayList(T[] array) {
    ArrayList<T> list = new ArrayList<T>();
    for(T elmt : array) list.add(elmt);
    return list;
}

如果没有帮助怎么办?那你做了什么?... JK :)
SᴀᴍOnᴇᴌᴀ

2

给定数组:

    int[] givenArray = {2,2,3,3,4,5};

将整数数组转换为整数列表

一种方法:boxed()->返回IntStream

    List<Integer> givenIntArray1 = Arrays.stream(givenArray)
                                  .boxed()
                                  .collect(Collectors.toList());

第二种方法:将流的每个元素映射到Integer,然后收集

注意: 使用mapToObj可以将每个int元素通过大小写i到(char)i转换为字符串流,char流等。

    List<Integer> givenIntArray2 = Arrays.stream(givenArray)
                                         .mapToObj(i->i)
                                         .collect(Collectors.toList());

将一种数组类型转换为另一种类型示例:

List<Character> givenIntArray2 = Arrays.stream(givenArray)
                                             .mapToObj(i->(char)i)
                                             .collect(Collectors.toList());

1

因此,这取决于您尝试使用的Java版本-

Java 7

 Arrays.asList(1, 2, 3);

要么

       final String arr[] = new String[] { "G", "E", "E", "K" };
       final List<String> initialList = new ArrayList<String>() {{
           add("C");
           add("O");
           add("D");
           add("I");
           add("N");
       }};

       // Elements of the array are appended at the end
       Collections.addAll(initialList, arr);

要么

Integer[] arr = new Integer[] { 1, 2, 3 };
Arrays.asList(arr);

在Java 8中

int[] num = new int[] {1, 2, 3};
List<Integer> list = Arrays.stream(num)
                        .boxed().collect(Collectors.<Integer>toList())

参考-http : //www.codingeek.com/java/how-to-convert-array-to-list-in-java/


1

您能否改善此答案,因为这是我使用的,但不是100%清楚。它工作正常,但是智能添加了新的WeatherStation [0]。为什么是0?

    public WeatherStation[] removeElementAtIndex(WeatherStation[] array, int index)
    {
        List<WeatherStation> list = new ArrayList<WeatherStation>(Arrays.asList(array));
        list.remove(index);
        return list.toArray(new WeatherStation[0]);
    }


我们为什么要改善您的问题?您要么知道答案,要么不知道答案。当然,您应该提供一个真正可以帮助他人的答案,而不是一个让您困惑的东西。
HimBromBeere

-2

使用两行代码将数组转换为列表,如果在整数值中使用它,则必须对原始数据类型使用自动装箱类型

  Integer [] arr={1,2};
  Arrays.asList(arr);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.