代码之家  ›  专栏  ›  技术社区  ›  fastcodejava

使用Java流将字母从A打印到Z

  •  15
  • fastcodejava  · 技术社区  · 6 年前

    我有这个代码,但它给了我一个错误:

    类型不匹配:无法从int转换为character

    Stream.iterate('a', i -> i + 1).limit(26).forEach(System.out::println);
    

    尽管可以写 int i = 'a';

    我知道我可以这样写,但对于一个简单的任务来说,这似乎是太多的代码了。

    Stream.iterate('a', i -> (char)(i + 1)).limit(26).forEach(System.out::println);
    

    为什么Java类型推理失败?

    2 回复  |  直到 6 年前
        1
  •  27
  •   Ousmane D.    6 年前

    原因何在 i -> i + 1 不编译是因为您试图 隐含地 转换一个 int 到A Character 编译器无法单独完成。

    换句话说,你可以想到 Stream.iterate('a', i -> i + 1) AS:

    Stream.iterate('a', (Character i) -> {
           int i1 = i + 1;  
           return i1; // not possible 
    });
    

    正如你所指出的, 明确地 铸造到 char 解决它:

    Stream.iterate('a', i -> (char)(i + 1))...
    

    顺便说一句,最好这样做:

    IntStream.rangeClosed('a', 'z').forEach(c -> System.out.println((char)c));
    

    这更好,因为:

    1. 没有拳击开销,因此效率更高
    2. 如果你停在说信 h 随着使用 iterate 你需要做更多的大脑处理,而不仅仅是进入 H 作为上限 rangeClosed 因为您需要找到截断无限流的数字。
    3. 和拳击一起 迭代 生成一个 无限的 流的开销比 有限的 一带 朗克洛斯 . 而且,跑起来容易得多 IntStream.rangeClosed 同时,这不是你想在这个特定的情况下,但这是需要记住的事情。这里有一些讨论 Generators as sources Brian Goetz。

    等。。。

        2
  •  17
  •   GBlodgett    6 年前

    只是:

    Stream.iterate('a', i -> ++i).limit(26).forEach(System.out::println);
    

    i -> i + 1 不起作用是因为 i 是一个 Character i + 1 导致隐式收缩转换( JLS 5.1.3 )这是不允许的。你可以 明确地 如图所示铸造。然而 ++i 工作是因为 JLS 15.15.1 ):

    在加法之前,对变量的值1和值执行二进制数字提升(_§5.6.2)。如有必要,通过缩小原始转换(_§5.1.3)和/或在存储变量之前对变量类型进行装箱转换(_§5.1.7)来缩小总和。

    这个 ++ 运算符负责缩小转换,而不必显式强制转换