这与此问题类似: How to convert int[] to Integer[] in Java?
我是Java的新手。如何在Java中将List<Integer>
转换为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;
}
我确信有更好的方法可以做到这一点。
答案 0 :(得分:478)
没有人提到Java 8中添加了流,所以这里是:
int[] array = list.stream().mapToInt(i->i).toArray();
思考过程:
Stream#toArray
会返回Object[]
,因此它不是我们想要的。此外Stream#toArray(IntFunction<A[]> generator)
无法满足我们的要求,因为通用类型A
无法代表原始int
int
的流会很好,因为它的toArray
方法很可能也会返回int[]
数组(返回其他内容,如{{1}或者甚至盒装Object[]
在这里会不自然)。幸运的是Java 8有这样的流:Integer[]
所以我们现在唯一需要弄清楚的是如何将IntStream
(将从Stream<Integer>
返回)转换为闪亮的list.stream()
。这里IntStream
方法来拯救。我们需要做的就是提供从mapToInt
到Integer
的一些映射。我们可以使用类似int
的内容返回Integer#getValue
:
int
(或者,如果有人更喜欢mapToInt( (Integer i) -> i.intValue())
)
但是使用拆箱可以生成类似的代码,因为编译器知道这个lambda的结果必须是mapToInt(Integer::intValue)
(int
中的lambda是mapToInt
接口的实现,它期望ToIntFunction
的主体1}}期望返回int applyAsInt(T value)
的方法。
所以我们可以简单地写
int
或更简单(因为mapToInt((Integer i)->i)
类型可以由编译器推断,因为Integer i
返回List<Integer>#stream()
)
Stream<Integer>
答案 1 :(得分:196)
不幸的是,由于Java处理原始类型,装箱,数组和泛型的性质,我不相信是更好的方法。特别是:
List<T>.toArray
无效,因为Integer
无法转换为int
int
用作泛型的类型参数,因此将作为int
特定的方法(或使用反射做的方法)讨厌的诡计)。我相信有些库为所有原始类型都有这种方法的自动生成版本(即有一个模板可以为每种类型复制)。这很难看,但这就是我害怕的方式:(
即使Arrays
类在泛型到达Java之前出现,如果它今天被引入,它仍然必须包含所有可怕的重载(假设你想使用原始数组)。
答案 2 :(得分:190)
除了Commons Lang,您可以使用Guava方法Ints.toArray(Collection<Integer> collection)
执行此操作:
List<Integer> list = ...
int[] ints = Ints.toArray(list);
这可以节省您必须自己进行Commons Lang等效的中间数组转换。
答案 3 :(得分:168)
最简单的方法是使用Apache Commons Lang。它有一个方便的ArrayUtils类,可以做你想要的。将toPrimitive
方法与重载一起用于Integer
s。
List<Integer> myList;
... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));
这样你就不会重新发明轮子了。 Commons Lang有许多Java遗漏的有用的东西。在上面,我选择创建一个正确大小的整数列表。您还可以使用0长度的静态Integer数组,让Java分配一个正确大小的数组:
static final Integer[] NO_INTS = new Integer[0];
....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));
答案 4 :(得分:49)
int[] toIntArray(List<Integer> list) {
int[] ret = new int[list.size()];
int i = 0;
for (Integer e : list)
ret[i++] = e;
return ret;
}
对代码进行轻微更改以避免昂贵的列表索引(因为List不一定是ArrayList,但可能是链接列表,随机访问很昂贵)
答案 5 :(得分:43)
Java 8 通过流程为我们提供了一种简单的方法...
使用集合stream()
函数然后映射到整数,您将获得一个IntStream。使用IntStream
,我们可以调用toArray(),它会为我们提供int []
int [] ints = list.stream().mapToInt(Integer::intValue).toArray();
答案 6 :(得分:12)
此
的 Java 8 单行代码ParallelCrawlerEngine
答案 7 :(得分:7)
我会在这里多扔一个。我注意到for循环的几种用法,但你甚至不需要循环内的任何东西。我之所以提到这一点,只是因为最初的问题是试图找到更简洁的代码。
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 i = 0,Iterator it ...
最后虽然(这部分仅仅是我的意见),如果您将有一个帮助功能或方法为您做某事,只需设置它并忘记它。它可以是一行或十行;如果你再也不会看到它,你就不会知道它的区别。
答案 8 :(得分:7)
如果您只是将Integer
映射到int
,那么您应该考虑using parallelism,因为您的映射逻辑不依赖于其范围之外的任何变量。
int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();
请注意这个
请注意,并行性并不比串行执行操作更快,尽管可能有足够的数据和处理器内核。虽然聚合操作使您能够更轻松地实现并行性,但您仍有责任确定您的应用程序是否适合并行性。
有两种方法可将整数映射到其原始形式:
通过ToIntFunction
。
mapToInt(Integer::intValue)
通过带有lambda表达式的显式unboxing。
mapToInt(i -> i.intValue())
通过lambda表达式隐式(自动)拆箱。
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();
处理lambda表达式中的null
。
int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
答案 9 :(得分:6)
这个简单的循环总是正确的!没有错误
int[] integers = new int[myList.size()];
for (int i = 0; i < integers.length; i++) {
integers[i] = myList.get(i);
}
答案 10 :(得分:5)
由于toArray返回一个Object []并且你无法从Object []转换为int []或者Integer []转换为int []
答案 11 :(得分:4)
int[] ret = new int[list.size()];
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {
ret[i] = iter.next();
}
return ret;
答案 12 :(得分:3)
还尝试Dollar(check this revision):
import static com.humaorie.dollar.Dollar.*
...
List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
答案 13 :(得分:2)
使用Eclipse Collections,如果您有java.util.List<Integer>
类型的列表,则可以执行以下操作:
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集合类型,则可以执行以下操作:
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 Collections的提交者
答案 14 :(得分:1)
我建议您使用java collections 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));
}
}
小心拳击/拆箱的缺点
答案 15 :(得分:0)
使用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);
}