如何在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
将不起作用,因为没有从Integer
到int
转换 - 你不能使用
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
- 所以最好有一些可以处理原始types
int
stream,因为它的toArray
方法很可能也会返回int[]
数组(返回类似于Object[]
东西,甚至boxedInteger[]
在这里都是不自然的)。 幸运的是,Java 8有这样的stream:IntStream
-
所以现在我们只需要弄清楚如何将
Stream<Integer>
(将从list.stream()
返回)转换为shiny的IntStream
。 这里mapToInt
方法来救援。 我们所要做的就是提供一些从Integer
到int
映射。 我们可以使用像Integer#getValue
这样的返回int
:mapToInt( (Integer i) -> i.intValue())
(或者如果有人喜欢
mapToInt(Integer::intValue)
)但类似的代码可以使用unboxing生成,因为编译器知道这个lambda的结果必须是
int
(mapToInt
lambda是ToIntFunction
接口的实现,它期望返回int
int applyAsInt(T value)
方法)。所以我们可以简单地写
mapToInt((Integer i)->i)
或更简单(因为
Integer i
types可以由编译器推断,因为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:
-
通过
ToIntFunction
。mapToInt(Integer::intValue)
-
通过lambdaexpression式显式拆箱 。
mapToInt(i -> i.intValue())
-
通过lambdaexpression式的隐式(自动)拆箱。
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();
-
在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; }