有人可以向我解释为什么以下代码不起作用吗?
我试图感受 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
.
但是我不明白为什么类型转换有问题。
最佳答案
对于第一种情况, 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)
解决此问题相反,然后你就不需要 Actor 了:
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[]
,因此不需要强制转换。
关于Java8 流和类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22426212/