web-dev-qa-db-ja.com

Java:for-eachを使用してコレクションをループする場合はiterator.hasNext()の代替

Javaリストのイテレータベースのループを_for-each_ステートメントに置き換えようとしていますが、コードはある時点でiterator.hasNext()を使用してリストの最後の要素に到達しました。

_for-each_の代替案に似たものはありますか?

_for (Object current : objectList) {
   if (last-element) 
      do-something-special
}
_
16
Dan Burzo

for-eachはイテレータバージョンの単なる構文糖衣であり、コンパイルされたバイトコードをチェックすると、コンパイラが実際にイテレータバージョンに変更していることがわかります。

For-eachフォームでは、要素が増えるかどうかを確認できません。その機能が必要な場合は、明示的なイテレータの使用を続けてください。

21
Mirek Pluta

ルノの答えに加えて:

Iterator<MyClass> it = myCollection.iterator();
while(it.hasNext()) {
  MyClass myClass = it.next():
  // do something with myClass
}

次のように変換されます。

for (MyClass myClass:myCollection) {
  // do something with myClass
}
8
Andreas_D

他の人が言ったように-これは不可能です。

Foreachコンストラクトがすべてではないことを覚えておいてください。 コレクションの各要素で同じ操作を実行するという非常に一般的なタスクを簡単に示すために導入されました。

あなたの場合、各要素に対してまったく同じことをしたくないので、foreachループはその仕事に適したツールではありません。これを行うためにそれを「ハック」しようとするのはばかげています。古典的なforループで明示的なイテレータを使用するだけです。

4
Andrzej Doyle

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
2
coobird

残念ながら、for eachイディオムでは、要素がリストの最初か最後かを確認できません。これは、foreachループの既知の制限です。イテレータを使い続けることをお勧めします。

たとえば、文字列の連結を行っている場合など、最後の要素ではなく最初の要素も確認できる場合は、次のように変更できます。

boolean first = true;
for (Element e : list) {
  if (!first) {
    //do optional operation
  }
  //do other stuff
  first = false;
}

しかし、私はイテレータを使用したいと思います。

1
Jorn

バイエルに加えて、メソッドgetLast()がないため、少し異なる方法で行う必要があります。ただし、その代わりに、このobjectList.size() - 1を使用できます。

for (Object current : objectList) {
   if (objectList.get(objectList.size() - 1).equals(current)) 
      do-something-special
}
0
Erik Wolf

これを実行したい場合は2つ考えられます。

    最後の要素に達した後で何かをする必要があります。この場合、コードをループの外に置く必要があります。
    
        for(Object item:theLinkedList){
    
        }
        System.out.println("something special")
    
    最後の要素を何らかの方法で変更するか、最後の要素に関連する情報を使用する必要があります。この場合、最後の要素にアクセスするには** LinkedList **を使用する必要があります

    for(Object item:theLinkedList){

    }
    Object last=theLinkedList.getLast();
    System.out.println("last");
0
Monachus

はい、できます。明示的なイテレータ構文を使用したくない場合は、次のようにします。

for (Object current : objectList) {
   if (objectList.getLast().equals(current)) 
      do-something-special
}
0
bayer

ループの繰り返し回数を保存するだけです、サンプル:

_    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_は配列に使用されます。

0
Alirezaa

あなたがのためにとどまりたいならば-それぞれ多分このような何か:

if (objectList.indexOf(current)==objectList.size()-1) break;
0
PeterMmm
int nElts = objectList.size();
int n = 0;
for (...) {
  if (++n == nElts) ...

私が考えることができる最高です。

0
Carl Smotricz