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

这是类似于这个问题: 如何在Java中将int []转换为Integer []?

我是Java新手。 我怎样才能将一个List<Integer>转换为Java中的int[] ? 我很困惑,因为List.toArray()实际上返回一个Object[] ,可以转换为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; } 

我相信有一个更好的方法来做到这一点。

不幸的是,由于Java处理原始types,装箱,数组和generics的性质,我不相信真的有更好的方法来做到这一点。 尤其是:

  • List<T>.toArray将不起作用,因为没有从Integerint转换
  • 你不能使用int作为generics的types参数,所以它必须是一个int特定的方法(或者使用reflection来做坏事的方法)。

我相信有这样的库有自动生成的所有基本types的这种方法的版本(即有一个为每个types复制的模板)。 这是丑陋的,但这就是我害怕:(

尽pipeArrays类在generics到达Java之前就已经出现了,但是如果它现在被引入(假设你想使用原始数组),它仍然必须包含所有可怕的过载。

没有人提到在Java 8中添加的stream,所以在这里:

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

思考过程:

  • 简单的Stream#toArray返回Object[] ,所以它不是我们想要的。 同样Stream#toArray(IntFunction<A[]> generator)不做我们想要的,因为genericstypesA不能表示原始的int
  • 所以最好有一些可以处理原始typesintstream,因为它的toArray方法很可能也会返回int[]数组(返回类似于Object[]东西,甚至boxed Integer[]在这里都是不自然的)。 幸运的是,Java 8有这样的stream: IntStream
  • 所以现在我们只需要弄清楚如何将Stream<Integer> (将从list.stream()返回)转换为shiny的IntStream 。 这里mapToInt方法来救援。 我们所要做的就是提供一些从Integerint映射。 我们可以使用像Integer#getValue这样的返回int

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

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

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

    所以我们可以简单地写

    mapToInt((Integer i)->i)

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

    mapToInt(i -> i)

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

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

这样可以节省您不得不按照Commons Lang等效的要求进行中间数组转换。

最简单的方法是使用Apache Commons Lang 。 它有一个方便的ArrayUtils类,可以做你想做的。 对于一个Integer数组,使用toPrimitive方法。

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

这样你就不会重新发明轮子。 Commons Lang有很多有用的东西,Java被遗漏了。 上面,我select了创build一个正确大小的整数列表。 您也可以使用长度为0的静态整数数组,并让Java分配一个正确大小的数组:

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

对代码稍作修改以避免昂贵的列表索引(因为列表不一定是一个ArrayList,但可能是一个链接列表,随机访问是昂贵的)

Java 8给了我们一个简单的方法来做到这一点,通过stream…

使用集合stream()函数,然后映射到整数,你会得到一个IntStream。 通过IntStream我们可以调用toArray(),它给了我们int []

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

到int []

到IntStream

这里是Java 8的单行代码

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

我会在这里再扔一个。 我已经注意到for循环的几个用法,但是你甚至不需要循环内部的任何东西。 我只是提到这一点,因为原来的问题是试图find不那么冗长的代码。

 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 ++的方式在for循环中多个声明,我们可以更进一步,并为(INT我= 0,迭代器…

最后(这部分只是我的意见),如果你要有一个帮助function或方法来为你做点事情,那就把它设置起来,忘掉它。 它可以是单线或十线; 如果你再也不看它,你将不会知道它的区别。

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

  int[] integers = new int[myList.size()]; for (int i = 0; i < integers.length; i++) { integers[i] = myList.get(i); } 
 int[] ret = new int[list.size()]; Iterator<Integer> iter = list.iterator(); for (int i=0; iter.hasNext(); i++) { ret[i] = iter.next(); } return ret; 

如果你只是把Integer映射到一个int那么你应该考虑使用并行 ,因为你的映射逻辑不依赖任何超出范围的variables。

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

只要知道这一点

请注意,并行性不会比连续执行操作的速度快,但可能是因为您拥有足够的数据和处理器内核。 虽然汇总操作使您可以更轻松地实现并行性,但仍然有责任确定您的应用程序是否适合并行。


有两种方法可以将整数映射到它们的原始forms:

  1. 通过ToIntFunction

     mapToInt(Integer::intValue) 
  2. 通过lambdaexpression式显式拆箱 。

     mapToInt(i -> i.intValue()) 
  3. 通过lambdaexpression式的隐式(自动)拆箱。

     mapToInt(i -> i) 

给定一个null值的列表

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

这里有三个选项来处理null

  1. 在映射之前过滤出null值。

     int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray(); 
  2. null值映射到默认值。

     int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray(); 
  3. 在lambdaexpression式中处理null

     int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray(); 

因为toArray返回一个Object [],并且你不能从Object []转换为int []或者Integer []转换为int [],所以你实际上没有办法“单线”

尝试也美元 ( 检查此修订 ):

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

使用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); } 

我build议你使用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)); } } 

谨防拳击/拆箱的弊端

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

 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集合types,则可以执行以下操作:

 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集合的提交者

 @Override public int findArray(int[] array, int[] subArray) { Map<Integer, Integer> map = new LinkedHashMap(); int index = -1; boolean flag = false; for (int i = 0; i < subArray.length; i++) { flag=false; for (int j = 0; j < array.length; j++) { if (subArray[i]==array[j]) { map.put(subArray[i], j); flag = true; } } } if (flag) { Map.Entry<Integer, Integer> entry = map.entrySet().iterator().next(); index = entry.getValue(); } return index; }