【问题标题】:Java8 streams and typecastsJava8 流和类型转换
【发布时间】:2023-03-18 17:44:02
【问题描述】:

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

我试图了解 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。 但我不明白为什么类型转换有问题。

【问题讨论】:

    标签: java casting java-8 java-stream


    【解决方案1】:

    对于第一种情况,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[],因此不需要在那里进行转换。

    【讨论】:

    • 代替.map(s->Integer.valueOf(s)),我认为你也可以使用.map(Integer::valueOf);:P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多