[解決済み] Java 8では、なぜArraysにはIterableのforEachメソッドが与えられなかったのですか?
疑問点
何か見落としているような気がするのですが。
Java 5 では
for-eachループ文(enhanced for loopとも呼ばれる)。
が導入されました。これは、主に
コレクション
. コレクション(またはコンテナ)クラスで
Iterable
インターフェイスは、"for-eachループ"を使用した反復処理の対象となります。おそらく歴史的な理由から、Javaの配列は
Iterable
インターフェイスを使用します。しかし、配列はどこにでもあった/あるものなので
javac
は、配列に対する for-each ループの使用 (従来の for ループと同等のバイトコードを生成) を許可します。
Java 8 では
forEach
メソッド
が追加されました。
Iterable
インターフェースに
デフォルト
というメソッドがあります。これにより、ラムダ式をコレクションに(反復しながら)渡すことが可能になった(例えば
list.forEach(System.out::println)
). しかし、やはり配列はこの扱いを受けられない。(回避策があることは理解しています)。
技術的な理由はありますか?
javac
での配列を受け入れるように拡張することはできませんでした。
forEach
拡張されたforループでそれらを受け入れるのと同じように?配列の実装を必要とせず、コード生成が可能なようです。
Iterable
. 私が甘いのでしょうか?
このことは、構文的に簡単だからということで、むしろ自然に配列を使っている言語の初心者にとっては、特に重要なことです。リストに切り替えて、その中で
Arrays.asList(1, 2, 3)
.
解決方法は?
Java言語とJVMには、配列に関する特殊なケースがたくさんあります。配列にはAPIがありますが、それはほとんど見えません。それは、配列が持っていると宣言されているようなものです。
-
implements Cloneable, Serializable
-
public final int length
-
public T[] clone()
ここでT
は配列のコンポーネント型です。
しかし、これらの宣言は、どこのソースコードにも表示されていません。参照
JLS 4.10.3
と
JLS 10.7
を解説しています。
Cloneable
と
Serializable
の呼び出しによって返されます。
Object[].class.getInterfaces()
おそらく驚くことに、この
length
フィールドと
clone()
メソッドは反射的に見えない。そのため
length
フィールドはフィールドではなく、これを使うと特別な
arraylength
のバイトコードです。の呼び出しは
clone()
は実際の仮想メソッド呼び出しになりますが、 レシーバーが配列型の場合、これはJVMによって特別に処理されます。
しかし、注目すべきは、配列クラスは
Iterable
インターフェイスを使用します。
Java SE 5 で拡張 for ループ ("for-each") が追加されたとき、右辺の式に 2 つの異なるケースがサポートされました。
Iterable
または配列型(
JLS 14.14.2
). その理由は
Iterable
インスタンスと配列では、enhanced-for文での扱いが全く異なります。JLSのそのセクションに詳しい扱いがありますが、もっと簡単に言うと、以下のような状況です。
に対して
Iterable<T> iterable
は、コード
for (T t : iterable) {
<loop body>
}
の構文解析です。
for (Iterator<T> iterator = iterable.iterator(); iterator.hasNext(); ) {
t = iterator.next();
<loop body>
}
配列の場合
T[]
の場合、コードは
for (T t : array) {
<loop body>
}
の構文解析です。
int len = array.length;
for (int i = 0; i < len; i++) {
t = array[i];
<loop body>
}
さて、なぜこのような形になったのでしょうか。確かに、配列に
Iterable
というのも、他のインターフェースはすでに実装されているからです。また、コンパイラが
Iterator
の実装は、配列にバックされています。(前例がある。コンパイラはすでに静的な
values()
と
valueOf()
メソッドが自動的に追加され、すべての
enum
クラスで説明されているように
JLS 8.9.3
.)
しかし、配列は非常に低レベルな構成であり、配列にアクセスするのは
int
の値は非常に安価な操作であることが期待されます。からのループインデックスを実行するのは非常にイディオムです。
0
を配列の長さ分、毎回1ずつ増やしていきます。配列に対するenhanced-forループはまさにこれを行う。もし、配列に対するenhanced-forループが
Iterable
プロトコルを使用する場合、配列をループする際に最初のメソッド呼び出しとメモリ割り当て (配列の上に
Iterator
その後、ループを1回繰り返すごとに2回のメソッド呼び出しが発生します。
そのため、デフォルトのメソッドが
Iterable
は、Java 8では配列に全く影響を与えませんでした。
他の方が指摘されているように、もし配列が
int
,
long
,
double
または参照型の場合、これをストリームに変換することができます。
Arrays.stream()
の呼び出しがあります。これによって
map()
,
filter()
,
forEach()
など。
しかし、Java言語とJVMにおける配列の特殊なケースは、次のように置き換えることができればいいと思います。 リアル という構文があります(2次元以上の配列の貧弱な処理、2^31の長さの制限など、他の多くの配列関連の問題の修正と一緒に)。これはJohn Roseが主導しているquot;Arrays 2.0"の調査の主題である。JVMLS 2012でのJohnの講演を参照してください( ビデオ , スライド ). この議論に関連するアイデアとしては、配列に対する実際のインタフェースの導入、ライブラリによる要素アクセスの補間、スライスやコピーといった追加操作のサポート、などがあります。
なお、これらはすべて調査であり、今後の課題です。この記事を書いている時点(2016-02-23)では、これらの配列の強化から、どのリリースのJavaロードマップにもコミットされているものはない。
関連
-
[解決済み] IntegerからBigIntegerへの変換
-
[解決済み] Javaでdoubleをfloatに変換する
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] List<Dog> は List<Animal> のサブクラスですか?Java のジェネリックはなぜ暗黙のうちに多相性にならないのですか?
-
[解決済み] Java のメソッド名を文字列で指定した場合、どのように呼び出すのですか?
-
[解決済み] Javaでリストを反復処理する方法
-
[解決済み] なぜJava 8のOptionalは引数で使ってはいけないのか
-
[解決済み] なぜJavaのmainメソッドは静的なのですか?
-
[解決済み] Java 8のインターフェイスメソッドで "final "が使えないのはなぜですか?
-
[解決済み】Stream<T>がIterable<T>を実装していないのはなぜですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Androidのコールバックとは何ですか?重複
-
[解決済み] javascriptでExpression言語を使うには?
-
[解決済み] mavenのコンパイルに失敗するのはなぜですか?
-
[解決済み] java.util.MissingFormatArgumentException: 形式指定子 '%s' がありません。
-
[解決済み] Javaにおけるシンボリック参照
-
[解決済み] 文字列が一意な文字であるかどうかを判定する
-
[解決済み] javaでメソッドを呼び出すプログラムのエラー修正
-
[解決済み] Java: getInstanceとStaticの比較
-
[解決済み] Spring ApplicationContext - リソースリーク: 'context' が閉じられない
-
[解決済み] x--やx++はここで何をするのですか?