1. ホーム

[解決済み】Java 8でString.chars()がintのストリームになるのはなぜですか?

2022-04-19 14:02:10

質問

Java 8 では、新しいメソッド String.chars() のストリームを返します。 int s ( IntStream )で文字コードを表します。という流れを期待する人が多いのでしょう。 char の代わりに、ここにあるのです。APIをこのように設計した動機は何だったのでしょうか。

どのように解決するのか?

すでに他の方もおっしゃっているように、この背景には、メソッドやクラスの爆発的な増加を防ぐという設計上の判断がありました。

それでも、個人的には、これは非常に悪い決定だったと思うし、彼らが望まないことを考えると、そこに CharStream の代わりに、別の方法を使用するのが合理的です。 chars() , と考えてしまいます。

  • Stream<Character> chars() この場合、ボックス文字のストリームが生成されるため、若干の性能劣化が生じます。
  • IntStream unboxedChars() これは、パフォーマンスコードに使用されるでしょう。

しかし を重視するのではなく なぜ この回答は、Java 8で手に入れたAPIでそれを実現する方法を示すことに焦点を当てるべきだと思います。

Java 7では、私はこのようにやっていました。

for (int i = 0; i < hello.length(); i++) {
    System.out.println(hello.charAt(i));
}

そして、Java 8でそれを行うための合理的な方法は、次のようなものだと思います。

hello.chars()
        .mapToObj(i -> (char)i)
        .forEach(System.out::println);

ここでは IntStream というラムダを使ってオブジェクトにマッピングします。 i -> (char)i に自動的にボックス化されます。 Stream<Character> そうすれば、やりたいことができるようになるし、プラスとしてメソッド参照も使えるようになる。

注意すること しかし、あなたは しなければならない する mapToObj を忘れて使ってしまった場合 map を使用すれば、何も文句は言われませんが、それでも結局は IntStream そして、なぜ文字を表す文字列ではなく、整数値が表示されるのか不思議に思うかもしれません。

Java 8 の他の醜い代替品。

を残すことで IntStream で、最終的に印刷したい場合、印刷のためにメソッド参照を使用することはできなくなります。

hello.chars()
        .forEach(i -> System.out.println((char)i));

さらに、自分のメソッドへのメソッド参照は、もう機能しません! 次のように考えてみましょう。

private void print(char c) {
    System.out.println(c);
}

そして

hello.chars()
        .forEach(this::print);

これは、非可逆変換がある可能性があるため、コンパイルエラーになります。

結論から言うと

を追加したくないという思いから、このようなAPIの設計になりました。 CharStream 個人的には、このメソッドは Stream<Character> で、現在のところ回避策としては mapToObj(i -> (char)i) の上に IntStream を使用すると、正しく動作させることができます。