Javaリストのイテレータベースのループを_for-each
_ステートメントに置き換えようとしていますが、コードはある時点でiterator.hasNext()
を使用してリストの最後の要素に到達しました。
_for-each
_の代替案に似たものはありますか?
_for (Object current : objectList) {
if (last-element)
do-something-special
}
_
for-eachはイテレータバージョンの単なる構文糖衣であり、コンパイルされたバイトコードをチェックすると、コンパイラが実際にイテレータバージョンに変更していることがわかります。
For-eachフォームでは、要素が増えるかどうかを確認できません。その機能が必要な場合は、明示的なイテレータの使用を続けてください。
ルノの答えに加えて:
Iterator<MyClass> it = myCollection.iterator();
while(it.hasNext()) {
MyClass myClass = it.next():
// do something with myClass
}
次のように変換されます。
for (MyClass myClass:myCollection) {
// do something with myClass
}
他の人が言ったように-これは不可能です。
Foreachコンストラクトがすべてではないことを覚えておいてください。 コレクションの各要素で同じ操作を実行するという非常に一般的なタスクを簡単に示すために導入されました。
あなたの場合、各要素に対してまったく同じことをしたくないので、foreachループはその仕事に適したツールではありません。これを行うためにそれを「ハック」しようとするのはばかげています。古典的なforループで明示的なイテレータを使用するだけです。
foreach
ループ(または拡張されたfor
ループ)には、現在繰り返されている要素を追跡する機能がありません。 Collection
のどのインデックスが処理されているか、またはIterable
で処理される要素が他にあるかどうかを確認する方法はありません。
とは言うものの、うまくいく回避策の1つは、現在foreach
ループで繰り返されているオブジェクトへの参照を保持することです。
現在の反復で処理されているものの参照を保持することにより、foreach
ループが終了すると参照を保持でき、変数に残っているものが最後の要素になります。
この回避策は、最後の要素が必要な唯一の要素である場合にのみ機能します。
例えば:
String lastString = null;
for (String s : new String[] {"a", "b", "c"}) {
// Do something.
// Keep the reference to the current object being iterated on.
lastString = s;
}
System.out.println(lastString);
出力:
c
残念ながら、for eachイディオムでは、要素がリストの最初か最後かを確認できません。これは、foreachループの既知の制限です。イテレータを使い続けることをお勧めします。
たとえば、文字列の連結を行っている場合など、最後の要素ではなく最初の要素も確認できる場合は、次のように変更できます。
boolean first = true;
for (Element e : list) {
if (!first) {
//do optional operation
}
//do other stuff
first = false;
}
しかし、私はイテレータを使用したいと思います。
バイエルに加えて、メソッドgetLast()
がないため、少し異なる方法で行う必要があります。ただし、その代わりに、このobjectList.size() - 1
を使用できます。
for (Object current : objectList) {
if (objectList.get(objectList.size() - 1).equals(current))
do-something-special
}
これを実行したい場合は2つ考えられます。
for(Object item:theLinkedList){
}
System.out.println("something special")
最後の要素を何らかの方法で変更するか、最後の要素に関連する情報を使用する必要があります。この場合、最後の要素にアクセスするには** LinkedList **を使用する必要があります
for(Object item:theLinkedList){
}
Object last=theLinkedList.getLast();
System.out.println("last");
はい、できます。明示的なイテレータ構文を使用したくない場合は、次のようにします。
for (Object current : objectList) {
if (objectList.getLast().equals(current))
do-something-special
}
ループの繰り返し回数を保存するだけです、サンプル:
_ int loop = 0;
for(Item item : items) {
if(loop == 0) {
//Is First Item
}
if(loop != items.size()-1) {
//Has Next Item
}
if(loop == items.size()-1) {
//Is Last Item
}
//Must Be Last Statement
loop++;
}
_
for(int i = 0; i < items.size(); i++)
ループに似ています。
items.size()
はリストに使用され、_items.length
_は配列に使用されます。
あなたがのためにとどまりたいならば-それぞれ多分このような何か:
if (objectList.indexOf(current)==objectList.size()-1) break;
int nElts = objectList.size();
int n = 0;
for (...) {
if (++n == nElts) ...
私が考えることができる最高です。