将原始长整型数组转换为长整型列表
这可能是一个有点简单的、办公桌式的问题,但令人惊讶的是,我的第一次尝试完全失败了。 我想获取一个原始长整型数组并将其转换为一个列表,我尝试这样做:
long[] input = someAPI.getSomeLongs();
List<Long> inputAsList = Arrays.asList(input); //Total failure to even compile!
正确的方法是什么?
This may be a bit of an easy, headdesk sort of question, but my first attempt surprisingly completely failed to work. I wanted to take an array of primitive longs and turn it into a list, which I attempted to do like this:
long[] input = someAPI.getSomeLongs();
List<Long> inputAsList = Arrays.asList(input); //Total failure to even compile!
What's the right way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
从 Java 8 开始,您现在可以使用流来实现:
Since Java 8 you can now use streams for that:
我发现使用 apache commons lang ArrayUtils 很方便(JavaDoc, Maven 依赖项)
它还更新了反向 API
编辑:,以按照评论和其他修复的建议提供对列表的完整转换。
I found it convenient to do using apache commons lang ArrayUtils (JavaDoc, Maven dependency)
it also has the reverse API
EDIT: updated to provide a complete conversion to a list as suggested by comments and other fixes.
hallidave 和jpalecek 有正确的想法是迭代数组,但它们没有利用 ArrayList 提供的功能:因为在这种情况下列表的大小是已知的,因此您可以应在创建 ArrayList 时指定它。
这样,就不会创建不必要的数组,而只是因为它们太短而被 ArrayList 丢弃,并且不会因为 ArrayList 高估其值而浪费空“槽”。空间要求。 当然,如果继续向列表添加元素,则需要一个新的后备数组。
hallidave and jpalecek have the right idea—iterating over an array—but they don't take advantage of a feature provided by
ArrayList
: since the size of the list is known in this case, you should specify it when you create theArrayList
.This way, no unnecessary arrays are created only to be discarded by the
ArrayList
because they turn out to be too short, and no empty "slots" are wasted becauseArrayList
overestimated its space requirements. Of course, if you continue to add elements to the list, a new backing array will be needed.有点详细,但这有效:
在您的示例中, Arrays.asList() 似乎将输入解释为 long[] 数组列表,而不是 Long 列表。 确实有点令人惊讶。 在这种情况下,自动装箱并不能按照您希望的方式工作。
A bit more verbose, but this works:
In your example it appears that Arrays.asList() is interpreting the input as list of long[] arrays instead of a list of Longs. A bit surprising, for sure. Autoboxing just doesn't work the way you want it to in this case.
作为另一种可能性,Guava 库将其提供为
Longs.asList()
,对于其他基本类型具有类似的实用程序类。As another possibility, the Guava library provides this as
Longs.asList()
, with similar utility classes for the other primitive types.问题询问如何将数组转换为列表。 到目前为止,大多数答案都展示了如何创建一个与数组内容相同的新列表,或引用第三方库。 但是,有一些简单的内置选项可用于此类转换。 其中一些已经在其他答案中概述(例如这个)。 但我想指出并详细说明此处实施的一定程度的自由度,并展示潜在的好处、缺点和注意事项。
有两个重要的区别:
这些选项将在此处快速总结,完整的示例程序显示在这个答案的底部。
创建新列表与在数组上创建视图
当结果应该是新列表时,则使用其他答案中的方法之一可以使用:
但应该考虑这样做的缺点:具有 1000000 个
long
值的数组将占用大约 8 MB 的内存。 新列表也将占用大约 8 MB。 当然,在创建此列表时必须遍历整个数组。 在许多情况下,创建新列表根本没有必要。 相反,在数组上创建一个视图就足够了:(请参阅底部的示例以了解
toList
方法的实现)在数组上拥有视图意味着数组中的更改将在列表中可见:
幸运的是,创建一个副本(即,一个不存在的新列表)从视图来看,受数组中修改的影响是微不足道的:
现在,这是一个真实的副本,相当于上面显示的基于流的解决方案所实现的效果。
创建可修改视图或不可修改视图
在许多情况下,列表只读就足够了>。 结果列表的内容通常不会被修改,而只会传递到仅读取列表的下游处理。
允许修改列表会引发一些问题:
可以在数组上创建可修改的列表视图。 这意味着列表中的更改(例如在某个索引处设置新值)将在数组中可见。
但不可能创建结构上可修改的列表视图。 这意味着不可能执行影响列表大小的操作。 这只是因为底层数组的大小无法更改。
以下是 MCVE,显示了不同的实现选项以及使用结果列表的可能方法:
显示了示例的输出这里:
The question asked about how to turn an array into a list. Most answers so far showed how to create a new list with the same contents as the array, or referred to third-party libraries. However, there are simple, built-in options for this sort of conversion. Some of them have already been sketched in other answers (e.g. this one). But I'd like to point out and elaborate certain degrees of freedom for the implementation here, and show the potential benefits, drawbacks and caveats.
There are at least two important distinctions to be made:
The options will be summarized here quickly, and a complete example program is shown at the bottom of this answer.
Creating a new list versus creating a view on the array
When the result should be a new list, then one of the approaches from the other answers may be used:
But one should consider the drawbacks of doing this: An array with 1000000
long
values will occupy roughly 8 Megabytes of memory. The new list will also occupy roughly 8 Megabytes. And of course, the full array has to be traversed while creating this list. In many cases, creating a new list is simply not necessary. Instead, it is sufficient to create a view on the array:(See the example at the bottom for an implementation of the
toList
method)The implication of having a view on the array are that changes in the array will be visible in the list:
Fortunately, creating a copy (that is, a new list that is not affected by modifications in the array) from the view is trivial:
Now, this is a true copy, equivalent to what is achieved with the stream-based solution that was shown above.
Creating a modifiable view or an unmodifiable view
In many cases, it will be sufficient when the list is read-only. The contents of the resulting list will often not be modified, but only passed to downstream processing that only reads the list.
Allowing for modifications of the list raises some questions:
It is possible to create a list view on the array that is modifiable. This means that changes in the list, like setting a new value at a certain index, will be visible in the array.
But it is not possible to create a list view that is structurally modifiable. This means that it is not possible to do operations that affect the size of the list. This is simply because the size of the underlying array cannot be changed.
The following is a MCVE showing the different implementation options, and the possible ways of using the resulting lists:
The output of the example is shown here:
不,没有从原始类型数组到装箱引用类型数组的自动转换。 你只能做
No, there is no automatic conversion from array of primitive type to array of their boxed reference types. You can only do
Java 8 的另一种方式。
Another way with Java 8.
我正在为这些问题编写一个小型库:
如果您关心的话,请检查此处。
I'm writing a small library for these problems:
In the case you care check it here.
Java 8 的另一种方式。
Another way with Java 8.
结合帕维尔和汤姆的答案我们得到这个
Combining Pavel and Tom's answers we get this
如果您想要与 Arrays.asList 类似的语义,那么您需要编写(或使用其他人的)List 的客户实现(可能通过 AbstractList > 它应该与 Arrays.asList 具有大致相同的实现,只是装箱和取消装箱值。
If you want similar semantics to
Arrays.asList
then you'll need to write (or use someone else's) customer implementation ofList
(probably throughAbstractList
. It should have much the same implementation asArrays.asList
, only box and unbox values.您可以使用 transmorph :
例如,如果源是整数数组,它也可以工作。
You can use transmorph :
It also works if source is an array of ints for example.
我知道这个问题已经足够老了,但是...您也可以编写自己的转换方法:
使用静态导入包含它后,可能的用法可能是:
或
I know this question is old enough, but... you can also write your own conversion method:
After you include it using static import, possible usages could be:
or
虽然可以创建一个新列表并向其中添加所有值(通过 for 循环或流),但我一直在处理非常大的数组,但性能很差。 因此,我创建了自己的易于使用的原始数组包装类。
示例:
在这里获取:
https://github.com/ Sf298/Sauds-Toolbox/blob/master/src/main/java/PrimitiveArrayWrapper/PrimitiveList.java
注意:我还没有完全测试它,所以如果您发现任何错误/问题,请告诉我。
While it is possible to create a new List and add all the values to it (via for loop or streams), I have been working on really big arrays and get poor performance. Therefore I created my own easy to use primitive array wrapper class.
Example:
Get it here:
https://github.com/Sf298/Sauds-Toolbox/blob/master/src/main/java/PrimitiveArrayWrapper/PrimitiveList.java
NOTE: I haven't fully tested it yet, so let me know if you find any bugs/issues.
您可以使用
LongStream
来实现You can use
LongStream
for that