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

2022-09-03 08:47:54

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

类型不匹配:无法从整型转换为字符

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 类型推断失败?


答案 1

不编译的原因是,您正在尝试将 a 隐式转换为编译器无法自行完成的 a。i -> i + 1intCharacter

换句话说,您可以将其视为:Stream.iterate('a', i -> i + 1)

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. 如果你要停止使用说字母,你必须做更多的大脑处理,而不仅仅是输入上限,因为你需要找到数字来截断无限流。hiteratehrangeClosed
  3. 随着拳击的出现,生成一个无限的流,在这种特定情况下,它的开销比有限的流具有更多的开销。此外,并行运行要容易得多,并不是说在这种特定情况下您希望这样做,而是要记住这一点。以下是Brian Goetz关于Generators作为来源的一些讨论。iteraterangeClosedIntStream.rangeClosed

等。。。


答案 2

怎么样, 只是:

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

i -> i + 1不起作用,因为 是 和 导致隐式缩小转换 (JLS 5.1.3),这是不允许的。您可以显式地投射它,如下所示。但是有效,因为(来自JLS 15.15.1):iCharacteri + 1++i

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

操作员负责缩小转换范围,而无需我们显式投射它++


推荐