Java8流和类型转换

eps*_*lbe 5 java casting java-8 java-stream

任何人都可以向我解释为什么以下代码不起作用?

我试图了解Java8的新功能并解决了BerlinClock Kata.在此期间,我不得不解析格式的字符串"hh:mm:ss"- 我想使用流并编写以下代码.

import java.util.Arrays;

private Integer[] parseTime (String time){
    Integer[] hhmmss = (Integer[]) Arrays.stream(time.split(":"))
                                         .map(s->Integer.parseInt(s)).toArray();
    return hhmmss;
}
Run Code Online (Sandbox Code Playgroud)

但运行时系统(我认为)抱怨显式类型转换(Integer[])无法完成.

据我所知,该Arrays.stream(time.split(":"))部分返回a Stream<String>,然后map(s->Integer.parseInt(s))将其转换为Stream<Integer>,然后toArray()生成一个Object[].现在Integer[]应该可以进行类型转换,因为中间流具有Integer类型参数.

请注意,我知道如何通过使用没有类型转换来解决此问题

int[] hhmmss= Arrays.stream(time.split(":")
                    .mapToInt(Integer::parseInt).toArray();
Run Code Online (Sandbox Code Playgroud)

并相应地更改类型签名int[] parseTime.但是我不明白为什么类型转换中存在问题.

Roh*_*ain 15

对于第一种情况,Stream#map()方法会给你一个Stream<Integer>,然后Stream#toArray()返回一个Object[]你需要强制转换的东西Integer[].但是在运行时,如果在内部Object[]创建而不是a ,则此强制转换可能会失败Integer[],这就是这里的情况.toArray()此流的方法源代码如下所示:

@Override
public final Object[] toArray() {
    return toArray(Object[]::new);
}
Run Code Online (Sandbox Code Playgroud)

你不能把它Object[]作为Integer[]参考.

您可以使用Stream#toArray(IntFunction)替代方法解决此问题,然后您不需要强制转换:

private Integer[] parseTime (String time){
    Integer[] hhmmss = Arrays.stream(time.split(":"))
                    .map(s->Integer.valueOf(s))
                    .toArray(Integer[]::new);
    return hhmmss;
}
Run Code Online (Sandbox Code Playgroud)

然而,在第二种情况下,Stream#mapToInt()方法给你一个IntStream,并IntStream#toArray()返回一个int[],因此不需要那里的转换.

  • 而不是`.map(s-> Integer.valueOf(s))`,我认为你也可以做`.map(Integer :: valueOf);`:P (3认同)