这个问题在这里已有答案:
这类似于这个问题: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 回答
不幸的是,由于Java处理原始类型,装箱,数组和泛型的性质,我不相信确实有更好的方法 . 特别是:
List<T>.toArray
赢了't work because there' s没有从Integer
转换为int
你不能使用
int
作为泛型的类型参数,因此它必须是int
特定的方法(或者使用反射来做恶意欺骗的方法) .我相信有些库为所有原始类型都有这种方法的自动生成版本(即有一个模板可以为每种类型复制) . 这很难看,但这就是我害怕的方式:(
即使Arrays类在泛型到达Java之前出现,如果它今天被引入(假设你想使用原始数组),它仍然必须包含所有可怕的重载 .
没有人提到Java 8中添加了流,所以这里:
思考过程:
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
方法来救援 . 我们需要做的就是提供从Integer
到int
的一些映射 . 我们可以使用Integer#getValue
这样返回int
的东西:mapToInt( (Integer i) -> i.intValue())
(或者,如果有人喜欢
mapToInt(Integer::intValue)
)但是类似的代码可以使用拆箱生成,因为编译器知道这个lambda的结果必须是
int
(mapToInt
中的lambda是ToIntFunction
接口的实现,它期望int applyAsInt(T value)
方法的主体预期返回int
) .所以我们可以简单地写
mapToInt((Integer i)->i)
或更简单(因为
Integer i
类型可以由编译器推断,因为List<Integer>#stream()
返回Stream<Integer>
)mapToInt(i -> i)
除了Commons Lang,你可以用Guava的方法Ints.toArray(Collection<Integer> collection)来做到这一点:
这可以节省您必须进行Commons Lang等效的中间数组转换 .
最简单的方法是使用Apache Commons Lang . 它有一个方便的ArrayUtils类,可以做你想要的 . 将toPrimitive方法与
Integer
数组的重载一起使用 .这样你就不会重新发明轮子 . Commons Lang有许多Java遗漏的有用的东西 . 在上面,我选择创建一个正确大小的整数列表 . 您还可以使用0长度的静态Integer数组,让Java分配一个正确大小的数组:
对代码进行轻微更改以避免昂贵的列表索引(因为List不一定是ArrayList,但可能是链表,随机访问很昂贵)
Java 8 通过溪流给我们一个简单的方法来做到这一点......
使用集合
stream()
函数,然后映射到整数,您将获得一个IntStream . 使用IntStream
,我们可以调用toArray()给我们int []
to int []
to IntStream
这是 Java 8 单行代码
我会在这里多扔一个 . 我注意到for循环的几种用法,但你甚至不需要循环内部的任何东西 . 我之所以提到这一点,只是因为最初的问题是试图找到更简洁的代码 .
如果Java在C语言中允许多次声明,我们可以更进一步,为(int i = 0,Iterator it ...
最后虽然(这部分仅仅是我的意见),如果你将有一个帮助功能或方法为你做一些事情,只需设置它并忘记它 . 它可以是一行或十行;如果你再也不去看它,你就不会知道它的区别 .
这个简单的循环总是正确的!没有错误
如果您只是将
Integer
映射到int
,那么您应该考虑using parallelism,因为您的映射逻辑不依赖于其范围之外的任何变量 .请注意这一点
将Integers映射到其原始形式有两种方法:
ToIntFunction
.给定一个
null
值的列表以下是处理
null
的三个选项:null
值 .null
值映射到默认值 .null
.因为toArray返回一个Object []而你无法从Object []转换为int []或Integer []转换为int [],所以实际上没有办法“单行” .
也试试Dollar(check this revision):
使用Eclipse Collections,如果您有
java.util.List<Integer>
类型的列表,则可以执行以下操作:如果您已经拥有类似MutableList的Eclipse集合类型,则可以执行以下操作:
注意:我是Eclipse Collections的提交者
我建议你使用java集合API中的
List<?>
骨架实现,在这种特殊情况下看起来非常有用:小心拳击/拆箱的缺点
使用lambda你可以这样做(在jdk lambda中编译):