5

谁能向我解释为什么以下代码不起作用?

我试图了解 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(":"))部分返回 a 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. 但我不明白为什么类型转换有问题。

4

1 回答 1

15

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

@Override
public final Object[] toArray() {
    return toArray(Object[]::new);
}

而且您不能将 anObject[]转换为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[],因此在那里不需要强制转换。

于 2014-03-15T16:12:10.487 回答