Philippe Beaudoin
Philippe Beaudoin

Reputation: 3310

Can I check the iteration variable to know if a foreach loop ran until the end Java?

In Java, I want to go through a list of elements and insert a new one at the right place. I was thinking of doing it in this way:

for( Tab tab : tabList )
  if( newTab.getPriority() < tab.getPriority() ) {
    newTab.insertBefore(tab);
    break;
  }
if( tab == null )
  newTab.insertBefore(endMarker);

Unfortunately, tab is not accessible outside the for loop. Is there any simple way to do what I want or do I have to use a boolean?

Upvotes: 2

Views: 484

Answers (9)

Kaleb Brasee
Kaleb Brasee

Reputation: 51945

Inside a foreach-style loop, I don't think you could know this. However, you could use an Iterator outside of the loop:

Iterator iter = tabList.iterator();
while (iter.hasNext()) {
  Tab newTab = iter.next();
  if( newTab.getPriority() < tab.getPriority() ) {
    newTab.insertBefore(tab);
    break;
  }
}

if (iter.hasNext()) {
  // You've still got elements left!
}

Upvotes: 0

polygenelubricants
polygenelubricants

Reputation: 383756

You can't access a foreach iterator variable outside of the loop since it goes out of scope. As you wrote it, the above code doesn't compile.

There's a variety of techniques that you can use, such as using the boolean that you mentioned. You can also use a "sentinel", a dummy tab that you put at the end of tabList that has a maximum priority that is reserved for this purpose (i.e. no "real" tab can have this priority). This guarantees that the if condition inside the loop will be true when you reach the sentinel tab.

Finally, you can also implement your Tab to be Comparable, or define a separate Comparator for it, and make tabList an ordered collection. This way, you don't even need a sentinel, or even a foreach loop; you can just add the newTab to the sorted collection and have it figure out where to insert it. If tabList is a TreeSet, for example, the insertion will be O(log n). The other techniques mentioned so far is O(n).

Upvotes: 2

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147164

The most obvious way to convert that into working code is:

insertBlock: {
    int newPriority = newTab.getPriority();
    for (Tab tab : tabs) {
        if (newPriority < tab.getPriority()) {
            newTab.insertBefore(tab);
            break insertBlock;
        }
    }
    newTab.insertBefore(endMarker);
}

Although it appears that not many people are familiar with the feature. As it happens, it was this feature that allows goto to be removed from the language.

Upvotes: 1

Bozho
Bozho

Reputation: 597114

This wouldn't compile, because of the scope of the tab variable. You can do the following

Tab lastTab = null;
for (Tab tab : tabList) {
    if (..) {
       ..
       lastTab = tab;
    }
}

Upvotes: 1

Sam
Sam

Reputation: 1886

Agreed with the above. I don't believe you can modify the tabList while it is being iterated either.

One alternate way of doing this is to find the position in the list you want to add into, and do the add operation then.

int i = 0;
for (; i < tabList.length; i++)
{
    if( newTab.getPriority() < tabList[i].getPriority() )
        break;
}

// this will shift the current item at that index value into the next one, and insert newtab into the specified index
tabList.add(i, newTab);

Upvotes: 0

Oli
Oli

Reputation: 239830

Instead of breaking you could raise an exception and catch it outside the loop. I forget the syntax in Java but Python would be something like this:

broken = False

try:
    for i in list:
        if i.condition == True:
            raise Exception
except Exception:
    # you know something has broken the flow
    broken = True

Although what if the last item broke? Technically speaking every item was inspected.

Upvotes: -2

fastcodejava
fastcodejava

Reputation: 41097

tab is not available outside for loop. You can so many things. Using a boolean is one of them.

Upvotes: 0

Otto Allmendinger
Otto Allmendinger

Reputation: 28268

It is better practice to use a tab variable outside the scope of the for loop

Tab selected_tab = null;

for ( Tab tab: tabList ) {
    if (tab_I_want(tab)) {
       selected_tab = tab;
       break;
    }
}

// selected_tab is either null or the tab you want

Upvotes: 2

Jeff Walden
Jeff Walden

Reputation: 7108

tab is scoped to the body of the for loop, if I remember my Java correctly (and if it works the way one would "expect", i.e. how for scoping works in C99 and C++), so this probably doesn't compile.

Upvotes: 0

Related Questions