使用Java 8中新增的流(Stream)功能,我们可以编写如下代码:
int[] example1 = list.stream().mapToInt(i->i).toArray();
int[] example2 = list.stream().mapToInt(Integer::intValue).toArray();
思考过程:
简单的`Stream#toArray`方法返回一个`Object[]`数组,不是我们想要的。同时,返回`A[]`的`Stream#toArray(IntFunction generator)`方法也无法解决问题,因为泛型类型`A`不能表示原始类型`int`。
所以最好有一种流来处理原始类型`int`,而不是像`Integer`这样的引用类型,因为它的`toArray`方法很可能也会返回一个`int[]`数组(返回其他类型如`Object[]`甚至装箱的`Integer[]`对于`int`来说是不自然的)。幸运的是,Java 8有这样一种流,即
IntStream
。
现在我们唯一需要解决的问题是如何将从`list.stream()`返回的`Stream`转换为那个闪亮的`IntStream`。
在寻找返回`IntStream`的方法时,我们可以快速搜索`Stream`文档,指向我们的解决方案,即
mapToInt(ToIntFunction mapper)
方法。我们需要做的就是提供从`Integer`到`int`的映射。
由于
ToIntFunction
是一个函数接口,我们也可以通过lambda表达式或方法引用提供它的实例。
无论如何,我们可以使用
Integer#intValue
将`Integer`转换为`int`,因此在`mapToInt`中我们可以写:
```
mapToInt((Integer i) -> i.intValue())
```
(或者某些人可能更喜欢:`mapToInt(Integer::intValue)`。)
但是,类似的代码也可以通过解包生成,因为编译器知道这个lambda的结果必须是`int`类型(在`mapToInt`中使用的lambda是`ToIntFunction`接口的实现,它期望一个返回`int`的方法作为其正文: `int applyAsInt(T value)`,这个方法应该返回一个`int`)。
因此,我们可以简单地编写:
```
mapToInt((Integer i)->i)
```
另外,由于编译器可以推断出`Stream#stream()`返回一个`Stream`,因此可以省略`(Integer i)`中的`Integer`类型,留下
```
mapToInt(i -> i)
```
Integer[] arr = (Integer[])list.toArray(new Integer[list.size]);
- Hardcoded