首页 文章

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

提问于
浏览
483

这个问题在这里已有答案:

这类似于这个问题:How to convert int[] to Integer[] in Java?

我是Java的新手 . 如何在Java中将 List<Integer> 转换为 int[] ?我很困惑,因为 List.toArray() 实际上返回 Object[] ,可以转换为nether Integer[]int[] .

现在我正在使用循环来执行此操作:

int[] toIntArray(List<Integer> list){
  int[] ret = new int[list.size()];
  for(int i = 0;i < ret.length;i++)
    ret[i] = list.get(i);
  return ret;
}

我相信有更好的方法可以做到这一点 .

16 回答

  • 186

    不幸的是,由于Java处理原始类型,装箱,数组和泛型的性质,我不相信确实有更好的方法 . 特别是:

    • List<T>.toArray 赢了't work because there' s没有从 Integer 转换为 int

    • 你不能使用 int 作为泛型的类型参数,因此它必须是 int 特定的方法(或者使用反射来做恶意欺骗的方法) .

    我相信有些库为所有原始类型都有这种方法的自动生成版本(即有一个模板可以为每种类型复制) . 这很难看,但这就是我害怕的方式:(

    即使Arrays类在泛型到达Java之前出现,如果它今天被引入(假设你想使用原始数组),它仍然必须包含所有可怕的重载 .

  • 6

    没有人提到Java 8中添加了流,所以这里:

    int[] array = list.stream().mapToInt(i->i).toArray();
    

    思考过程:

    • simple Stream#toArray 返回 Object[] ,所以它不是我们想要的 . 此外 Stream#toArray(IntFunction<A[]> generator) 没有做我们想要的,因为泛型类型 A 不能代表原始 int

    • 所以有一些流可以处理原始类型 int 会很好,因为它的 toArray 方法很可能也会返回 int[] 数组(返回其他类似 Object[] 或甚至盒装 Integer[] 这里不自然) . 幸运的是Java 8有这样的流: IntStream

    • 所以现在我们唯一需要弄清楚的是如何将 Stream<Integer> (将从 list.stream() 返回)转换为闪亮的 IntStream . 这里 mapToInt 方法来救援 . 我们需要做的就是提供从 Integerint 的一些映射 . 我们可以使用 Integer#getValue 这样返回 int 的东西:

    mapToInt( (Integer i) -> i.intValue())

    (或者,如果有人喜欢 mapToInt(Integer::intValue)

    但是类似的代码可以使用拆箱生成,因为编译器知道这个lambda的结果必须是 intmapToInt 中的lambda是 ToIntFunction 接口的实现,它期望 int applyAsInt(T value) 方法的主体预期返回 int ) .

    所以我们可以简单地写

    mapToInt((Integer i)->i)

    或更简单(因为 Integer i 类型可以由编译器推断,因为 List<Integer>#stream() 返回 Stream<Integer>

    mapToInt(i -> i)

  • 434

    除了Commons Lang,你可以用Guava的方法Ints.toArray(Collection<Integer> collection)来做到这一点:

    List<Integer> list = ...
    int[] ints = Ints.toArray(list);
    

    这可以节省您必须进行Commons Lang等效的中间数组转换 .

  • 2

    最简单的方法是使用Apache Commons Lang . 它有一个方便的ArrayUtils类,可以做你想要的 . 将toPrimitive方法与 Integer 数组的重载一起使用 .

    List<Integer> myList;
     ... assign and fill the list
    int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));
    

    这样你就不会重新发明轮子 . Commons Lang有许多Java遗漏的有用的东西 . 在上面,我选择创建一个正确大小的整数列表 . 您还可以使用0长度的静态Integer数组,让Java分配一个正确大小的数组:

    static final Integer[] NO_INTS = new Integer[0];
       ....
    int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));
    
  • 5
    int[] toIntArray(List<Integer> list)  {
        int[] ret = new int[list.size()];
        int i = 0;
        for (Integer e : list)  
            ret[i++] = e;
        return ret;
    }
    

    对代码进行轻微更改以避免昂贵的列表索引(因为List不一定是ArrayList,但可能是链表,随机访问很昂贵)

  • 6

    Java 8 通过溪流给我们一个简单的方法来做到这一点......

    使用集合 stream() 函数,然后映射到整数,您将获得一个IntStream . 使用 IntStream ,我们可以调用toArray()给我们 int []

    int [] ints = list.stream().mapToInt(Integer::intValue).toArray();
    

    to int []

    to IntStream

  • 180

    这是 Java 8 单行代码

    public int[] toIntArray(List<Integer> intList){
           return intList.stream().mapToInt(Integer::intValue).toArray();
    }
    
  • 12

    我会在这里多扔一个 . 我注意到for循环的几种用法,但你甚至不需要循环内部的任何东西 . 我之所以提到这一点,只是因为最初的问题是试图找到更简洁的代码 .

    int[] toArray(List<Integer> list) {
        int[] ret = new int[ list.size() ];
        int i = 0;
        for( Iterator<Integer> it = list.iterator(); 
             it.hasNext(); 
             ret[i++] = it.next() );
        return ret;
    }
    

    如果Java在C语言中允许多次声明,我们可以更进一步,为(int i = 0,Iterator it ...

    最后虽然(这部分仅仅是我的意见),如果你将有一个帮助功能或方法为你做一些事情,只需设置它并忘记它 . 它可以是一行或十行;如果你再也不去看它,你就不会知道它的区别 .

  • 166

    这个简单的循环总是正确的!没有错误

    int[] integers = new int[myList.size()];
      for (int i = 0; i < integers.length; i++) {
          integers[i] = myList.get(i);
      }
    
  • 0

    如果您只是将 Integer 映射到 int ,那么您应该考虑using parallelism,因为您的映射逻辑不依赖于其范围之外的任何变量 .

    int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();
    

    请注意这一点

    请注意,并行性并不比串行执行操作更快,尽管如果你有足够的话数据和处理器核心 . 虽然聚合操作使您能够更轻松地实现并行性,但您仍有责任确定您的应用程序是否适合并行性 .


    将Integers映射到其原始形式有两种方法:

    • 通过 ToIntFunction .
    mapToInt(Integer::intValue)
    
    mapToInt(i -> i.intValue())
    
    • 通过lambda表达式隐式(自动)拆箱 .
    mapToInt(i -> i)
    

    给定一个 null 值的列表

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

    以下是处理 null 的三个选项:

    • 在映射之前过滤掉 null 值 .
    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
    • null 值映射到默认值 .
    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
    • 在lambda表达式中处理 null .
    int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
    
  • 3
    int[] ret = new int[list.size()];       
    Iterator<Integer> iter = list.iterator();
    for (int i=0; iter.hasNext(); i++) {       
        ret[i] = iter.next();                
    }                                        
    return ret;
    
  • 4

    因为toArray返回一个Object []而你无法从Object []转换为int []或Integer []转换为int [],所以实际上没有办法“单行” .

  • 1

    也试试Dollarcheck this revision):

    import static com.humaorie.dollar.Dollar.*
    ...
    
    List<Integer> source = ...;
    int[] ints = $(source).convert().toIntArray();
    
  • 49

    使用Eclipse Collections,如果您有 java.util.List<Integer> 类型的列表,则可以执行以下操作:

    List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
    int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();
    
    Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
    

    如果您已经拥有类似MutableList的Eclipse集合类型,则可以执行以下操作:

    MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
    int[] ints = integers.asLazy().collectInt(i -> i).toArray();
    
    Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
    

    注意:我是Eclipse Collections的提交者

  • 3

    我建议你使用java集合API中的 List<?> 骨架实现,在这种特殊情况下看起来非常有用:

    package mypackage;
    
    import java.util.AbstractList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    public class Test {
    
    //Helper method to convert int arrays into Lists
    static List<Integer> intArrayAsList(final int[] a) {
        if(a == null)
            throw new NullPointerException();
        return new AbstractList<Integer>() {
    
            @Override
            public Integer get(int i) {
                return a[i];//autoboxing
            }
            @Override
            public Integer set(int i, Integer val) {
                final int old = a[i];
                a[i] = val;//auto-unboxing
                return old;//autoboxing
            }
            @Override
            public int size() {
                return a.length;
            }
        };
    }
    
    public static void main(final String[] args) {
        int[] a = {1, 2, 3, 4, 5};
        Collections.reverse(intArrayAsList(a));
        System.out.println(Arrays.toString(a));
    }
    }
    

    小心拳击/拆箱的缺点

  • 32

    使用lambda你可以这样做(在jdk lambda中编译):

    public static void main(String ars[]) {
            TransformService transformService = (inputs) -> {
                int[] ints = new int[inputs.size()];
                int i = 0;
                for (Integer element : inputs) {
                    ints[ i++ ] = element;
                }
                return ints;
            };
    
            List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };
    
            int[] results = transformService.transform(inputs);
        }
    
        public interface TransformService {
            int[] transform(List<Integer> inputs);
        }
    

相关问题