有人可以向我解释为什么下面的代码不起作用吗?
我试图了解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;
}
但运行时系统(我认为)抱怨显式类型转换(Integer[])
无法完成。
据我了解,Arrays.stream(time.split(":"))
部分返回Stream<String>
,然后map(s->Integer.parseInt(s))
将其转换为Stream<Integer>
,然后toArray()
生成Object[]
}}。现在,由于中间流具有Integer[]
类型参数,因此应该可以对Integer
进行类型转换。
请注意,我知道如何在不使用
进行类型转换的情况下解决此问题int[] hhmmss= Arrays.stream(time.split(":")
.mapToInt(Integer::parseInt).toArray();
并相应地将类型签名更改为int[] parseTime
。
但我不明白为什么类型转换中存在问题。
答案 0 :(得分:15)
对于第一种情况,Stream#map()
方法会为您提供Stream<Integer>
,然后Stream#toArray()
会返回Object[]
,您需要将其转换为Integer[]
。但是在运行时,如果在内部创建Object[]
而不是Integer[]
,则此强制转换可能会失败,这就是这里的情况。此流的toArray()
方法的源代码如下所示:
@Override
public final Object[] toArray() {
return toArray(Object[]::new);
}
并且您无法将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;
}
然而,在第二种情况下,Stream#mapToInt()
方法会为您提供IntStream
,而IntStream#toArray()
会返回int[]
,因此不需要进行投射。