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

我使用了Arrays.asList(),但行为(和签名)不知怎么地从Java SE 1.4.2(文档现在存档)改变到8,我在web上找到的大多数代码片段都使用1.4.2行为。

例如:

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

在1.4.2返回一个包含元素1,2,3的列表 在1.5.0+上返回包含数组'numbers'的列表

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

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

问题是在Java 5中引入了可变参数,不幸的是,Arrays.asList()也重载了一个可变参数版本。因此arrays. aslist (numbers)被Java 5编译器理解为int数组的可变参数。

这个问题在Effective Java第二版,第7章,第42项中有更详细的解释。


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

但是,您可以使用包装int原语的Integer类来拥有一个List<Integer>。使用数组将数组转换为List。asList实用程序方法。

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

请在IdeOne.com上查看实时运行的代码。


你必须转换为数组

Arrays.asList((Object[]) array)

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

最后,我不得不做一个“手动”转换:

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

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


说到转换方式,这取决于你为什么需要你的列表。 如果你只需要读取数据。好的,给你:

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

第一种方法实际上不转换数组,但“表示”它像一个列表。但是数组的所有属性都在底层,比如固定数量的元素。请注意,在构造ArrayList时需要指定类型。


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

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

如果你使用Apache common -lang,另一个解决方法是:

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

ArrayUtils的地方。toObject将int[]转换为Integer[]


我们不能有List<int>,因为int是一个基本类型,所以我们只能有List<Integer>。

Java 16

Java 16在Stream API上引入了一个名为toList()的新方法。这个方便的方法返回一个包含流元素的不可修改的List。因此,尝试向列表中添加新元素只会导致UnsupportedOperationException异常。

int[] ints = new int[] {1,2,3,4,5};
Arrays.stream(ints).boxed().toList();

Java 8 (int array)

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

需要数组列表而不是列表?

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

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

为什么不能在结构上修改list21 ?

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

需要明确的是,list21可以被修改,我们可以调用list21.set(index,element),但这个列表不能在结构上被修改,即不能从列表中添加或删除元素。你也可以查看我的这个答案,以获得更多解释。


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

List<Integer> list22 = 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(真正不可变列表):

我们可以使用List。Java 9中引入的。还有其他方式:

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


一行程序:

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

更短:

List<Integer> list = Arrays.asList(1, 2, 3, 4);

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

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

注意:

注意collector .<Integer>toList(),这个泛型方法可以帮助你避免错误“类型不匹配:不能从List<Object>转换到List<Integer>”。


使用数组

这是将数组转换为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!

使用数组列表或其他列表实现

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

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

在Java 8中使用流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));

参见:

为什么我们在Java中使用自动装箱和解箱? 什么时候用链表代替数组列表?


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

  Integer [] arr={1,2};
  List<Integer> listInt=Arrays.asList(arr);

因此,这取决于您正在尝试的Java版本

Java 7

 Arrays.asList(1, 2, 3);

OR

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

OR

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/


我也遇到过同样的问题,写了一个泛型函数,它接受一个数组,并返回一个具有相同内容的相同类型的ArrayList:

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

在Java 9中,您可以通过新的方便的工厂方法List.of使用更优雅的不可变列表:

List<String> immutableList = List.of("one","two","three");

(无耻地从这里抄袭)


使用番石榴: Integer[] array = {1,2,3}; List<Integer> List = Lists.newArrayList(sourceArray); 使用Apache Commons Collections: Integer[] array = {1,2,3}; List<Integer> List = new ArrayList<>(6); CollectionUtils。addAll(列表、数组);


给定的数组:

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

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

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

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

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

注意: 使用mapToObj你可以隐蔽每个int元素到字符串流,字符流等套管i (char)i

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

你能不能改进这个答案,因为这是我使用的,但我不是100%清楚。它工作正常,但intelliJ增加了新的气象站[0]。为什么是0 ?

公共气象站[]removeElementAtIndex(气象站[]数组,int索引) { List<WeatherStation> List = new ArrayList<WeatherStation>(Arrays.asList(array)); list.remove(指数); 返回列表。toArray(新WeatherStation [0]); }


使用此函数将Array arr转换为List。 Arrays.stream (arr) .collect (Collectors.toList ());

定义泛型方法将数组转换为列表的示例:

public <T> List<T> fromArrayToList(T[] a) {   
    return Arrays.stream(a).collect(Collectors.toList());
}

从Java 8开始,应该执行以下操作

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

如果您正在尝试优化内存等(并且不想引入外部库),那么实现您自己的不可变“数组视图列表”比您想象的要简单——您只需要扩展java.util.AbstractList。

class IntArrayViewList extends AbstractList<Integer> {
    int[] backingArray;
    int size;

    IntArrayViewList(int[] backingArray, int size) {
        this.backingArray = backingArray;
        this.size = size;
    }

    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int i = 0;

            @Override
            public boolean hasNext() {
                return i < size;
            }

            @Override
            public Integer next() {
                return get(i++);
            }
        };
    }

    public int size() {
        return size;
    }

    public Integer get(int i) {
        return backingArray[i];
    }
}

Int是一个原语。原语不能接受空值,只能有默认值。因此,要接受null,您需要使用包装器类Integer。

选项1:

int[] nos = { 1, 2, 3, 4, 5 };
Integer[] nosWrapped = Arrays.stream(nos).boxed()   
                                        .toArray(Integer[]::new);
nosWrapped[5] = null // can store null

选项2: 您可以使用任何使用包装器类Integer的数据结构

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

为了解决这个问题,我开始尝试减少准备一些测试用例输入的代码量。我看到很多人试图在Arrays.asList()中包含高级和新特性,但下面的代码选择了简单性:

    //Integer input[]
    List<Integer> numbers = Arrays.asList(new Integer[]{1, 2 ,3, 4, 5, 4, 3, 2, 1, 3, 4});
    
    //String input[]
    List<String> names = Arrays.asList(new String[]{"Jhon", "Lucas", "Daniel", "Jim", "Sam"});
    
    //String input[]
    List<Character> letters = Arrays.asList(new Character[]{'A', 'B', 'K', 'J', 'F'});
    

请注意,匿名数组示例只适用于非基本类型的数组,因为API使用泛型,这就是为什么你可以看到几个2行示例,更多信息在这里:为什么Java泛型不支持基本类型?

对于较新的jdk,还有另一个更简单的选择,下面的例子与上面展示的例子相同:

    //Integer
    List<Integer> numbers = Arrays.asList(1, 2 ,3, 4, 5, 4, 3, 2, 1, 3, 4);
    
    //String
    List<String> names = Arrays.asList("Jhon", "Lucas", "Daniel", "Jim", "Sam"); 
    
    //Character
    List<Character> letters = Arrays.asList('A', 'B', 'K', 'J', 'F');