51

多くの Java フレームワーク クラスは を実装していますがIterable、実装Stringしていません。String通常の配列内のアイテムを反復できるのと同じように、 a 内の文字を反復することは理にかなっています。

String実装しない理由はありますIterableか?

4

8 に答える 8

29

本当に良い答えはありません。Java の反復子は、個別の項目 (オブジェクト) のコレクションに特に適用されます。Stringを実装するCharSequenceは、個別の文字の「コレクション」であるべきだと考えるでしょう。代わりに、文字で構成される単一のエンティティとして扱われます。

Java では、イテレータは実際にはコレクションにのみ適用され、文字列には適用されないようです。このようになる理由はありません (私が知る限り、おそらく Gosling または API ライターと話をする必要があるでしょう)。それは慣習または設計上の決定のようです。実際、実装を妨げる ものは何もありません。CharSequenceIterable

つまり、次のように文字列内の文字を反復処理できます。

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

または:

for(char c : str.toCharArray()) {
  System.out.println(c);
}

または:

"Java 8".chars().forEach(System.out::println);

また、文字列は不変であるため、文字列の文字をその場で変更できないことに注意してください。String の変更可能なコンパニオンは StringBuilder (または古い StringBuffer) です。

編集

この回答に対するコメントに基づいて明確にする。にIterator がない理由について、考えられる理論的根拠を説明しようとしていStringます。不可能だと言っているわけではありません。CharSequence確かに、実装するのは理にかなっていると思いますIterable

Stringを提供しますCharSequence。これは、概念的にのみ、 とは異なりStringます。AStringは通常、単一のエンティティと考えられていますが、 A はCharSequenceまさにそれであり、一連の文字です。文字のシーケンス (つまり、 on CharSequence) にイテレータを使用することは理にかなっていますが、単にStringそれ自体にではありません。

Foxfire がコメントで正しく指摘しているようにString、インターフェイスを実装しているCharSequenceため、型的には aStringは aCharSequenceです。意味的には、それらは 2 つの別個のものであるように思われます。ここではおそらく衒学的に説明していますが、私が を考えるときは、String通常、たまたま複数の文字で構成される単一のエンティティとして考えます。1, 2, 3, 4数字の並びと数字の違いを考えてみましょう1234abcdここで、文字列と文字列の違いを考えてみましょうa, b, c, d。私はこの違いを指摘しようとしています。

私の意見では、イテレータがない理由を尋ねることは、個々の数字を反復処理できるようにイテレータがないString理由を尋ねるようなものです。Integer

于 2010-05-05T11:02:05.053 に答える
13

理由は簡単です。文字列クラスは Iterable よりもずっと古いからです。

そして明らかに、誰も String にインターフェースを追加したいとは思っていませんでした (まったく同じ考えに基づいた CharSequence を実装しているため、これは少し奇妙です)。

ただし、 Iterable は object を返すため、多少パフォーマンスが低下します。したがって、返されるすべての Char をラップする必要があります。

編集:ちょうど比較: .Net は文字列の列挙をサポートしていますが、.Net では Iterable はネイティブ型でも機能するため、Java で必要なラッピングは必要ありません。

于 2010-05-05T11:11:57.947 に答える
12

私の同僚である Josh Bloch は、こ​​の機能を Java 7 に追加することを強く望んでいます。

for (char c : aString) { ... }

for (int codePoint : aString) { ... }

これは、文字と論理文字 (コード ポイント) をループする最も簡単な方法です。ボクシングを強制的に行うStringimplementを作成する必要はありません。Iterable

その言語機能がなければ、この問題に対する本当に良い答えはありません。そして、彼はこれを実現できると非常に楽観的に見えますが、私には確信が持てません。

于 2010-05-05T22:56:58.223 に答える
3

彼らは単にそうするのを忘れていました。

于 2010-05-26T10:19:51.313 に答える
2

String を Iterable に実装する主な理由の 1 つは、前述の単純な for(each) ループを有効にすることです。したがって、 String を Iterable に実装しない理由は、結果をボックス化する必要があるため、ナイーブな実装に固有の非効率性である可能性があります。ただし、結果のイテレーター (String.iterator() によって返される) の実装が最終的なものである場合、コンパイラーはそれを特殊ケースにして、ボックス化/ボックス化解除のないバイトコードを生成できます。

于 2010-06-04T07:04:04.900 に答える
1

ここで反復することに本当に関心がある場合:

String str = "StackOverflow";

for (char c: str.toCharArray()){
     //here you go
}
于 2010-05-05T11:04:15.247 に答える
-1

Iterableなにかの?Iterable<Integer>各要素が Unicode コードポイントを表す場合、最も理にかなっています。を持っていてもIterable<Character>遅くて無意味toCharArrayです。

于 2010-05-05T11:59:23.463 に答える