如何将 List转换为Java 中的 int[] ?
如何在 Java 中将 List
转换为 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 中将 int[] 转换为 Integer[]?< /em>.
How can I convert a List<Integer>
to int[]
in Java?
I'm confused because List.toArray()
actually returns an Object[]
, which can be cast to neither Integer[]
nor int[]
.
Right now I'm using a loop to do so:
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;
}
Is there's a better way to do this?
This is similar to the question
How can I convert int[] to Integer[] in Java?.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
通过 Java 8 中添加的流,我们可以编写如下代码:
思考过程:
简单的
Stream#toArray
返回一个Object[]
数组,因此它不是我们想要的想。另外,返回A[]
的 Stream#toArray(IntFunction Generator) 并不能满足我们的要求,因为泛型类型A
无法表示原始类型int
因此,最好有某种设计为处理原始类型
int
的流像Integer
这样的引用类型,因为它的toArray
方法很可能也会返回一个int[]
数组(返回像Object[]
甚至装箱的Integer[]
对于int
来说都是不自然的)。幸运的是,Java 8 有这样一个流,它是 <代码>IntStream所以现在我们唯一需要弄清楚的是如何转换我们的
Stream
(它将从list 返回.stream()
) 到闪亮的IntStream
。在
Stream
文档中快速搜索,同时寻找返回IntStream
的方法,这为我们指明了我们的解决方案,即mapToInt(ToIntFunction 映射器)
方法。我们需要做的就是提供从Integer
到int
的映射。自
ToIntFunction
是函数接口,我们还可以通过lambda或方法引用提供它的实例。无论如何,要将 Integer 转换为 int,我们可以使用
Integer#intValue
所以在mapToInt
中我们可以这样写:(或者有些人可能更喜欢:
mapToInt(Integer::intValue)
。)但是可以使用拆箱生成类似的代码,因为编译器知道此 lambda 的结果必须是 int 类型(
mapToInt
中使用的 lambda 是一个实现ToIntFunction
接口的主体,该接口期望类型为int applyAsInt(T value)
的方法作为主体,该方法预计返回一个int
)。< /p>所以我们可以简单地写:
此外,由于
(Integer i)
中的Integer
类型可以由编译器推断出来,因为List#stream()
返回一个Stream
,我们也可以跳过它,留下With streams added in Java 8 we can write code like:
Thought process:
The simple
Stream#toArray
returns anObject[]
array, so it is not what we want. Also,Stream#toArray(IntFunction<A[]> generator)
which returnsA[]
doesn't do what we want, because the generic typeA
can't represent the primitive typeint
So it would be nice to have some kind of stream which would be designed to handle primitive type
int
instead of the reference type likeInteger
, because itstoArray
method will most likely also return anint[]
array (returning something else likeObject[]
or even boxedInteger[]
would be unnatural forint
). And fortunately Java 8 has such a stream which isIntStream
So now the only thing we need to figure out is how to convert our
Stream<Integer>
(which will be returned fromlist.stream()
) to that shinyIntStream
.Quick searching in documentation of
Stream
while looking for methods which returnIntStream
points us to our solution which ismapToInt(ToIntFunction<? super T> mapper)
method. All we need to do is provide a mapping fromInteger
toint
.Since
ToIntFunction
is functional interface we can also provide its instance via lambda or method reference.Anyway to convert Integer to int we can use
Integer#intValue
so insidemapToInt
we can write:(or some may prefer:
mapToInt(Integer::intValue)
.)But similar code can be generated using unboxing, since the compiler knows that the result of this lambda must be of type
int
(the lambda used inmapToInt
is an implementation of theToIntFunction
interface which expects as body a method of type:int applyAsInt(T value)
which is expected to return anint
).So we can simply write:
Also, since the
Integer
type in(Integer i)
can be inferred by the compiler becauseList<Integer>#stream()
returns aStream<Integer>
, we can also skip it which leaves us with不幸的是,由于 Java 处理原始类型、装箱、数组和泛型的性质,我不认为真的有更好的方法来做到这一点。特别是:
List.toArray
不起作用,因为没有从Integer
到int
的转换int
作为泛型的类型参数,因此它必须是一种int
特定的方法(或者使用反射来进行令人讨厌的欺骗的方法)。我相信有些库为所有原始类型提供了这种方法的自动生成版本(即有一个为每种类型复制的模板)。它很丑陋,但恐怕就是这样:(
尽管
Arrays
类在泛型到达 Java 之前就出现了,如果今天引入它,它仍然必须包含所有可怕的重载(假设您想使用原始数组) 。Unfortunately, I don't believe there really is a better way of doing this due to the nature of Java's handling of primitive types, boxing, arrays and generics. In particular:
List<T>.toArray
won't work because there's no conversion fromInteger
toint
int
as a type argument for generics, so it would have to be anint
-specific method (or one which used reflection to do nasty trickery).I believe there are libraries which have autogenerated versions of this kind of method for all the primitive types (i.e. there's a template which is copied for each type). It's ugly, but that's the way it is I'm afraid :(
Even though the
Arrays
class came out before generics arrived in Java, it would still have to include all the horrible overloads if it were introduced today (assuming you want to use primitive arrays).除了 Commons Lang 之外,您还可以使用 Guava 的方法
Ints.toArray (Collection集合)
:这样您就不必自己进行 Commons Lang 等效项所需的中间数组转换。
In addition to Commons Lang, you can do this with Guava's method
Ints.toArray(Collection<Integer> collection)
:This saves you having to do the intermediate array conversion that the Commons Lang equivalent requires yourself.
最简单的方法是使用 Apache Commons Lang。它有一个方便的 ArrayUtils 类,可以做你想做的事情。使用
toPrimitive
方法,具有Integer
数组的重载。这样你就不会重新发明轮子。 Commons Lang 有很多 Java 所遗漏的有用的东西。在上面,我选择创建一个适当大小的整数列表。您还可以使用 0 长度的静态整数数组,并让 Java 分配正确大小的数组:
The easiest way to do this is to make use of Apache Commons Lang. It has a handy ArrayUtils class that can do what you want. Use the
toPrimitive
method with the overload for an array ofInteger
s.This way you don't reinvent the wheel. Commons Lang has a great many useful things that Java left out. Above, I chose to create an Integer list of the right size. You can also use a 0-length static Integer array and let Java allocate an array of the right size:
Java 8 为我们提供了一种通过流来完成此操作的简单方法...
使用集合
stream()
函数,然后映射到整数,您将获得一个 IntStream。使用IntStream
我们可以调用 toArray() ,它给我们int []
到 int []
到 IntStream
Java 8 has given us an easy way to do this via streams...
Using the collections
stream()
function and then mapping to ints, you'll get an IntStream. With theIntStream
we can call toArray() which gives usint []
to int []
to IntStream
用途:
对代码的这一微小更改是为了避免昂贵的列表索引(因为列表不一定是 ArrayList,但它可能是链表,对于其随机访问来说成本很高)。
Use:
This slight change to your code is to avoid expensive list indexing (since a List is not necessarily an ArrayList, but it could be a linked list, for which random access is expensive).
下面是一个 Java 8 单行代码:
Here is a Java 8 single line code for this:
如果您只是将
Integer
映射到int
那么您应该考虑 使用并行性,因为您的映射逻辑不依赖于其范围之外的任何变量。请注意这一点
有两种方法可以将整数映射到其原始形式:
通过
ToIntFunction
。通过使用 lambda 表达式显式拆箱。
通过使用 lambda 表达式隐式(自动)拆箱。
给定一个带有
null
值的列表以下是处理
null
的三个选项:在映射之前过滤掉
null
值。将
null
值映射到默认值。在 lambda 表达式中处理
null
。If you are simply mapping an
Integer
to anint
then you should consider using parallelism, since your mapping logic does not rely on any variables outside its scope.Just be aware of this
There are two ways to map Integers to their primitive form:
Via a
ToIntFunction
.Via explicit unboxing with lambda expression.
Via implicit (auto-) unboxing with lambda expression.
Given a list with a
null
valueHere are three options to handle
null
:Filter out the
null
values before mapping.Map the
null
values to a default value.Handle
null
inside the lambda expression.这个简单的循环总是正确的!没有错误
This simple loop is always correct! no bugs
我注意到 for 循环的多种用途,但您甚至不需要循环内的任何内容。我提到这一点只是因为最初的问题是试图找到不太冗长的代码。
如果 Java 允许像 C++ 那样在 for 循环中进行多个声明,我们可以更进一步,执行 for(int i = 0, Iterator it...
但最后(这部分只是我的观点),如果你想要一个帮助你做某事的功能或方法,只需设置它并忘记它,如果你再也不会看它,它可以是一行或十行;不会知道其中的区别。
I've noticed several uses of for loops, but you don't even need anything inside the loop. I mention this only because the original question was trying to find less verbose code.
If Java allowed multiple declarations in a for loop the way C++ does, we could go a step further and do for(int i = 0, Iterator it...
In the end though (this part is just my opinion), if you are going to have a helping function or method to do something for you, just set it up and forget about it. It can be a one-liner or ten; if you'll never look at it again you won't know the difference.
实际上没有办法“单行”你想要做的事情,因为 toArray 返回一个 Object[] 并且你不能从 Object[] 转换为 int[] 或 Integer[] 转换为 int[] 。
There is really no way of "one-lining" what you are trying to do, because toArray returns an Object[] and you cannot cast from Object[] to int[] or Integer[] to int[].
另请尝试美元 (检查此修订版):
Also try Dollar (check this revision):
使用 Eclipse Collections,如果您有
java.util 类型的列表,则可以执行以下操作.List
:如果您已经有一个 Eclipse Collections 类型,例如
MutableList
,您可以执行以下操作:注意:我是 Eclipse Collections 的提交者
With Eclipse Collections, you can do the following if you have a list of type
java.util.List<Integer>
:If you already have an Eclipse Collections type like
MutableList
, you can do the following:Note: I am a committer for Eclipse Collections
我建议您使用 Java 集合 API 中的
List
骨架实现。在这种特殊情况下,它似乎非常有帮助:谨防装箱/拆箱缺点。
I would recommend you to use the
List<?>
skeletal implementation from the Java collections API. It appears to be quite helpful in this particular case:Beware of boxing/unboxing drawbacks.
使用 lambda 你可以这样做(在 JDK lambda 中编译):
Using a lambda you could do this (compiles in JDK lambda):