Могу ли я проверить переменную итерации, чтобы узнать, работал ли цикл foreach до конца Java? - PullRequest
2 голосов
/ 28 февраля 2010

В Java я хочу просмотреть список элементов и вставить новый в нужном месте.Я думал о том, чтобы сделать это следующим образом:

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

К сожалению, tab недоступен вне цикла for.Есть ли простой способ сделать то, что я хочу, или я должен использовать логическое значение?

Ответы [ 9 ]

2 голосов
/ 28 февраля 2010

Лучше использовать переменную tab вне области действия for цикла

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
2 голосов
/ 28 февраля 2010

Вы не можете получить доступ к переменной итератора foreach вне цикла, поскольку она выходит из области видимости. Как вы написали, приведенный выше код не компилируется.

Существует множество методов, которые вы можете использовать, например, использование boolean, которое вы упомянули. Вы также можете использовать « sentinel », фиктивную вкладку, которую вы ставите в конце tabList, с максимальным приоритетом, который зарезервирован для этой цели (т.е. никакая «настоящая» вкладка не может иметь этот приоритет ). Это гарантирует, что условие if внутри цикла будет истинным, когда вы перейдете на вкладку часового.

Наконец, вы также можете реализовать свой Tab как Comparable или определить для него отдельный Comparator и сделать tabList упорядоченной коллекцией. Таким образом, вам даже не нужен часовой или даже цикл foreach; Вы можете просто добавить newTab в отсортированную коллекцию и указать, куда ее вставить. Например, если tabList - это TreeSet, вставка будет O(log n). Другие методы, упомянутые до сих пор, O(n).

1 голос
/ 28 февраля 2010

Самый очевидный способ преобразовать это в рабочий код:

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

Хотя кажется, что не многие люди знакомы с этой функцией. Как оказалось, именно эта функция позволяет удалить из языка goto.

1 голос
/ 28 февраля 2010

Это не скомпилируется из-за области действия переменной tab. Вы можете сделать следующее

Tab lastTab = null;
for (Tab tab : tabList) {
    if (..) {
       ..
       lastTab = tab;
    }
}
0 голосов
/ 28 февраля 2010

Согласен с вышесказанным. Я не верю, что вы можете изменить tabList, пока он повторяется.

Один альтернативный способ сделать это - найти позицию в списке, в которую вы хотите добавить, и затем выполнить операцию добавления.

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);
0 голосов
/ 28 февраля 2010

Вместо взлома может вызвать исключение и перехватить его за пределами цикла. Я забыл синтаксис в Java, но Python будет выглядеть примерно так:

broken = False

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

Хотя что, если последний предмет сломался? Технически говоря, каждый предмет был проверен.

0 голосов
/ 28 февраля 2010

Внутри цикла в стиле foreach, я не думаю, что вы могли бы знать это. Однако вы можете использовать итератор вне цикла:

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!
}
0 голосов
/ 28 февраля 2010

tab недоступно снаружи для цикла. Вы можете так много вещей. Использование boolean является одним из них.

0 голосов
/ 28 февраля 2010

tab находится в теле цикла for, если я правильно помню свой Java (и если он работает так, как можно было бы ожидать, т.е. как for scoping работает в C99 и C ++), так что это, вероятно, не компилируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...