如何在Java中将int[]转换为List<Integer>?

570

如何在Java中将int[]转换为List<Integer>

当然,除了逐个循环项之外,我对任何其他答案都很感兴趣。但如果没有其他答案,我会选择那个作为最佳答案,以显示这个功能不是Java的一部分。


我们可以利用IntStream.Of(array).collect(Collectors.toList)。 - Saroj Kumar Sahoo
1
@SarojKumarSahoo:在IntStream中,没有单参数的collect方法。 - John McClane
1
没有内置的方法来做到这一点。你必须手动完成,声明一个ArrayList并将int数组中的每个值都添加到ArrayList中。真是遗憾! - Zhou Haibo
21个回答

564

在Java 8及以上版本中,您可以将int数组转换为流。调用Arrays.streamIntStream.of
  • 调用IntStream#boxed以使用从int原始类型到Integer对象的装箱转换。
  • 使用Stream.collect(Collectors.toList())收集为列表。或者更简单地,在Java 16+中调用Stream#toList()

    例子:

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

    在 Java 16 及更高版本中:
    List<Integer> list = Arrays.stream(ints).boxed().toList();
    

  • 27
    等同于:Arrays.stream(ints).boxed().collect(Collectors.toList()); (这是Java代码,将int数组转换为整数列表) - njfrost
    4
    你说得对,IntStream.of 只是调用 Arrays.stream,所以我按照你的建议改进了答案。 - mikeyreilly
    2
    由于某些原因,这似乎在Android Studio上没有返回预期的结果类型(在eclipse上工作)。它说,期望List<Integer>,但发现List<Object>。 - Eugenio Lopez
    2
    看起来很简洁明了,但是当我在LeetCode上使用它与@willcodejavaforfood提供的基本解决方案相比时,程序的性能在内存和运行时间方面都有所下降。 - chitresh sirohi
    1
    @chitreshsirohi 这是因为在流中使用lambda函数会导致Java生成一些匿名类。 - Ashvin Sharma
    显示剩余4条评论

    351

    int[]转换为List<Integer>没有捷径可走,因为Arrays.asList方法不会自动装箱,它只会创建一个List<int[]>对象,这并不是你想要的结果。你需要编写一个实用方法来完成转换。

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

    34
    最好使用数组的大小来初始化列表。 - David Rabinowitz
    114
    对于(int i : ints),将ints中的每一个整数i添加到intList中。 - Stephen Denne
    18
    @willcodejavaforfood - David的意思是,这样做会更好:new ArrayList<Integer>(ints.length); - Stephen Denne
    12
    在构建 ArrayList 时声明其大小可以避免在添加一定数量后出现内部调整大小的情况,虽然好处可能不大,但肯定有好处。 - Grundlefleck
    13
    new ArrayList<Integer>() {{ for (int i : ints) add(i); }} 可以翻译为:创建一个新的 ArrayList<Integer> 对象,并将 ints 中的元素添加到该对象中。具体实现方式是使用双括号初始化语法,在第一对括号内创建一个匿名子类,第二对括号内使用实例初始化器来执行循环并添加元素。 - user4910279
    显示剩余10条评论

    194

    还有来自guava库的内容... com.google.common.primitives.Ints:

    List<Integer> Ints.asList(int...)
    

    13
    这应该是正确答案。看看问题的第二句话:“当然,我对除了逐个循环项目之外的任何其他答案都感兴趣。” - josketres
    3
    这里有一些细微之处。返回的列表使用提供的数组作为后备存储器,因此您不应该改变数组。该列表也不保证所包含的整数对象的身份。也就是说,list.get(0) == list.get(0) 的结果没有明确规定。 - pburka
    1
    在添加库时,要注意Android上的方法引用计数。不过这是个好发现。 - milosmns
    在Android中,我必须将implementation 'com.google.firebase:firebase-crashlytics-buildtools:2.9.0'添加到build.gradle才能使其正常工作。 - Donald Duck

    116

    Arrays.asList不能像其他答案所期望的那样工作。

    这段代码不会创建一个包含10个整数的列表。它将打印1而不是10

    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    List lst = Arrays.asList(arr);
    System.out.println(lst.size());
    

    这将创建一个整数列表:

    List<Integer> lst = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    

    如果您已经有一个整数数组,则没有快速的方法可以进行转换,最好使用循环。

    另一方面,如果您的数组中包含对象而不是原始数据类型,则Arrays.asList将起作用:

    String str[] = { "Homer", "Marge", "Bart", "Lisa", "Maggie" };
    List<String> lst = Arrays.asList(str);
    

    10
    请注意,该列表是不可变的。 - Danielson
    4
    上面的评论中,Arrays.asList(arr)会生成类型为List<int[]>的列表,该类型与List<Integer>不兼容。如果尝试将输出分配给变量,如下所示:List l = Arrays.asList(arr);则会出现以下错误 | Error: | incompatible types: inference variable T has incompatible bounds | equality constraints: java.lang.Integer | lower bounds: int[] | List<Integer> l = Arrays.asList(a); | ^--------------^ - Vishal Seshagiri
    1
    这是错误的!它会生成List<int[]>。 - d2k2

    56

    我将用另一种方法添加另一个答案;没有循环,而是使用一个匿名类来利用自动装箱功能:

    public List<Integer> asList(final int[] is)
    {
        return new AbstractList<Integer>() {
                public Integer get(int i) { return is[i]; }
                public int size() { return is.length; }
        };
    }
    

    1
    +1 这个比我的短,但是我的适用于所有原始类型。 - dfa
    7
    与创建ArrayList相比,使用速度更快且占用更少内存,但代价是List.add()和List.remove()无法使用。 - Stephen Denne
    3
    对于稀疏访问模式下的大型数组,我很喜欢这个解决方案,但对于频繁访问的元素,它将导致许多不必要的 Integer 实例化(例如,如果您多次访问相同的元素100次)。此外,您需要定义一个迭代器,并在返回值中包装 Collections.unmodifiableList。 - Adamski
    @Christoffer 谢谢。我已经添加了 set 方法,现在我甚至可以对数组进行排序... - freedev

    46

    最简单的代码片段如下:

    public List<Integer> myWork(int[] array) {
        return Arrays.asList(ArrayUtils.toObject(array));
    }
    

    ArrayUtils来自commons-lang库 :)


    12
    请注意,ArrayUtils 是一个相对较大的库,适用于 Android 应用程序。 - msysmilu
    1
    相反的操作在这里描述:https://dev59.com/cXNA5IYBdhLWcg3wcNbF#960507 ArrayUtils.toPrimitive (...) 是关键。 - ZeroOne

    37

    在Java 8中使用流:

    int[] ints = {1, 2, 3};
    List<Integer> list = new ArrayList<Integer>();
    Collections.addAll(list, Arrays.stream(ints).boxed().toArray(Integer[]::new));
    

    或者使用Collectors

    List<Integer> list =  Arrays.stream(ints).boxed().collect(Collectors.toList());
    

    4
    为什么不直接使用收集器? - assylias

    24

    在Java 8中:

    int[] arr = {1,2,3};
    IntStream.of(arr).boxed().collect(Collectors.toList());
    

    23

    如果你正在使用Java 8,我们可以使用Stream API将其转换为列表。

    List<Integer> list = Arrays.stream(arr)     // IntStream 
                                    .boxed()        // Stream<Integer>
                                    .collect(Collectors.toList());
    

    您也可以使用IntStream进行转换。

    List<Integer> list = IntStream.of(arr) // return Intstream
                                        .boxed()        // Stream<Integer>
                                        .collect(Collectors.toList());
    

    还有其他的外部库,如guava和apache commons可用于转换。

    干杯。


    13
    这个错误报告也值得一看,它被关闭的原因是“不是一个缺陷”,并附有以下文字:
    “整个数组的自动装箱行为没有指定的行为,这是有充分理由的。 对于大型数组来说,这可能是非常昂贵的。”

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接