[解決済み] なぜJavaはイテレータに対するforeachを許さないのか(イテレータブルに対してのみ)?重複
質問
重複の可能性があります。
なぜJavaのIteratorはIterableではないのですか?
foreachループは、私の知る限りJava5で追加されたシンタックスシュガーです。そのため
Iterable<O> iterable;
for(O o : iterable) {
// Do something
}
と同じバイトコードを生成します。
Iterable<O> iterable;
for(Iterator<O> iter = iterable.iterator(); iter.hasNext(); /* NOOP */) {
O o = iter.next();
// Do something
}
しかし、そもそも反復子がなく、イテレータしかない場合(例えば、クラスが2つの異なるイテレータを提供しているため)、構文糖のforeachループは使えません。もちろん、古いスタイルの反復処理を行うことはできます。しかし、私は実際にやってみたいのです。
Iterator<O> iter;
for(O o : iter /* Iterator<O>, not Iterable<O>! */) {
// Do something
}
そしてもちろん、偽の
Iterable
:
class Adapter<O> implements Iterable<O> {
Iterator<O> iter;
public Adapter(Iterator<O> iter) {
this.iter = iter;
}
@Override
public Iterator<O> iterator() {
return iter;
}
}
(実際には、一度しか反復できないので、Iterable API の醜い乱用です!)
もしそれが
Iterator
を中心に設計されていれば、多くの面白いことができるかもしれません。
for(O o : iterable.iterator()) {} // Iterate over Iterable and Collections
for(O o : list.backwardsIterator()) {} // Or backwards
Iterator<O> iter;
for(O o : iter) {
if (o.something()) { iter.remove(); }
if (o.something()) { break; }
}
for(O : iter) { } // Do something with the remaining elements only.
誰か知っていますか?
なぜ
はこのように設計されたのでしょうか?曖昧さを避けるために、あるクラスが
Iterator
と
Iterable
? "for(O o : iter)" がすべての要素を2回処理する(そして新しいイテレータを取得するのを忘れる)と仮定したプログラマのエラーを回避するためですか?それとも、何か他の理由があるのでしょうか?
あるいは、私が知らないだけで、何か言語のトリックがあるのでしょうか?
どのように解決するのですか?
というわけで、なんとなく納得のいく説明ができました。
短いバージョンです。 この構文は 配列 にも適用されるからです。
もし構文が
Iterator
を中心に構文を設計した場合、配列と矛盾してしまいます。3つのバリエーションを挙げてみましょう。
A) をJavaの開発者が選択しました。
Object[] array;
for(Object o : array) { }
Iterable<Object> list;
for(Object o : list) { }
Iterator<Object> iter;
while(iter.hasNext()) { Object o = iter.next(); }
も同じような挙動をし 一貫性が高い です。 しかし、イテレータは古典的なイテレーションスタイルを使用しなければなりません(少なくとも、エラーを引き起こす可能性は低いです)。
B)
は、配列と
Iterators
:
Object[] array;
for(Object o : array) { }
Iterable<Object> list;
for(Object o : list.iterator()) { }
Iterator<Object> iter;
for(Object o : iter) { }
さて、配列とコレクションは矛盾していますが、配列とArrayListは非常に密接に関連しており、同じように動作するはずです。さて、もしどこかの時点で、言語が
を拡張しました。
を拡張して、例えば配列に
Iterable
を実装するようにすると、矛盾が生じます。
C) は3つとも許可します。
Object[] array;
for(Object o : array) { }
Iterable<Object> list;
for(Object o : list) { }
Iterator<Object> iter;
for(Object o : iter) { }
さて、もし誰かが
両方
Iterable
と
Iterator
(forループは新しいイテレータを取得するのか、それとも現在のイテレータを反復するのか - ツリー状の構造では簡単に発生します!?). Iterable beats Iterator" のような単純なタイブレーカーでは、残念ながらうまくいきません:それは突然、実行時対コンパイル時の違いとジェネリックの問題を導入してしまいます。
今、突然、私たちはコレクション/イテレータブルまたは配列に対して反復処理したいかどうかに注意を払う必要があり、その時点で私たちは大きな混乱の代償としてほとんど利益を得ていません。
Javaにおける"for each"の方法(A)は非常に一貫しており、プログラミング上のエラーはほとんど発生せず、配列を通常のオブジェクトに変えるという将来起こりうる変化を可能にします。
バリアントがあります
D)
もおそらく問題なく動作するでしょう。
for-each for Iterators only. 好ましくは
.iterator()
メソッドをプリミティブ配列に追加することが望ましいです。
Object[] array;
for(Object o : array.iterator()) { }
Iterable<Object> list;
for(Object o : list.iterator()) { }
Iterator<Object> iter;
for(Object o : iter) { }
しかし、これではコンパイラだけでなく実行環境にも変更を加える必要があり、後方互換性が壊れてしまいます。さらに、言及された混乱はまだ存在しており
Iterator<Object> iter;
for(Object o : iter) { }
for(Object o : iter) { }
一度だけデータを繰り返し処理します。
関連
-
型に解決できない エラー解決
-
[解決済み] Javaはパラメータのデフォルト値をサポートしていますか?
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み] なぜ ++[[]][+[] +[+[]] は "10" という文字列を返すのでしょうか?
-
[解決済み] Could not find or load main class "とはどういう意味ですか?
-
[解決済み] Javaの「for each」ループはどのように機能するのですか?
-
[解決済み] なぜJavaにはtransientフィールドがあるのですか?
-
[解決済み] 特定のUnicode文字を含むコメントでのJavaコードの実行が許可されているのはなぜですか?
-
[解決済み] Javaでリストを反復処理する方法
-
[解決済み】Javaではfinallyブロックは必ず実行されるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
実行中にEclipseがポップアップする A Java Exception has occurred
-
Java の switch case 文で必要な定数式の問題の解決法
-
名前 'XXX' を持つ Bean の作成に失敗しました。自動依存関係の注入に失敗しました 解決方法
-
BindException: アドレスはすでに使用中です:バインドエラー解決
-
XXX型を囲むインスタンスがJavaでアクセスできない
-
java send https request prompt java.security.cert.について。
-
JDK8 の Optional.of と Optional.ofNullable メソッドの違いと使い方を説明する。
-
Web Project JavaでPropertiesファイルを読み込むと、「指定されたファイルがシステムで見つかりません」というソリューションが表示されます。
-
ApiModel と @ApiModelProperty の使用法
-
[解決済み] なぜJavaのIteratorはIterableではないのですか?