Разобрать строку в JSON - PullRequest
1 голос
/ 12 июля 2010

Я анализирую эту строку JSON с помощью libs в org.json, и я не могу понять, почему я получаю вывод в журнал ниже.

ArrayList<String> al = new ArrayList<String>();
JSONObject demo = new JSONObject("{\"00408C88A2E6\":{\"id\":\"00408C88A2E6\",\"name\":\"Lab\"},\"00408C91188B\":{\"id\":\"00408C91188B\",\"name\":\"Lab1\"},\"00408C944B99\":{\"id\":\"00408C944B99\",\"name\":\"Lato1\"},\"00408C944BA0\":{\"id\":\"00408C944BA0\",\"name\":\"Lato\"}}");
Iterator<String> iterator =  demo.keys();
while (iterator.hasNext() ){    
  al.add((String)iterator.next());
  Log.i(LOG_TAG, "size al into while " + al.size());
  Log.i(LOG_TAG, "MAC " + iterator.next() + " for the user " + userId);
} 

Вывод журнала

07-12 08:55:34.056: INFO/parse(285): size al into while 1
07-12 08:55:34.056: INFO/parse(285): MAC 00408C91188B for the user nweb
07-12 08:55:34.066: INFO/parse(285): size al into while 2
07-12 08:55:34.066: INFO/parse(285): MAC 00408C944B99 for the user nweb
07-12 08:55:34.066: INFO/parse(285): size al 2

Не должно иметь 4 элемента в моем ArrayList?Спасибо

1 Ответ

5 голосов
/ 12 июля 2010

Вы дважды назвали iterator.next() в теле цикла. Каждый раз, когда вы делаете, итератор продвигается вперед.

Возможно, вы захотите вызвать его один раз в теле и сохранить в локальной переменной.

String next = iterator.next();
al.add(next);
Log.i(LOG_TAG, "MAC " + next + " for the user " + userId);

Обратите внимание, что Iterator<E> определяет E next(), поэтому вам не нужно приводить к String в этом случае.


Еще один иллюстративный пример

Вот пример из Руководство по языку Java / Для каждого цикла :

Вот распространенная ошибка, которую люди делают, когда пытаются сделать вложение итерация по двум коллекциям:

List suits = ...;
List ranks = ...;
List sortedDeck = new ArrayList();

// BROKEN - throws NoSuchElementException!
for (Iterator i = suits.iterator(); i.hasNext(); )
    for (Iterator j = ranks.iterator(); j.hasNext(); )
        sortedDeck.add(new Card(i.next(), j.next()));

Можете ли вы обнаружить ошибку? Не расстраивайся, если не можешь. Многие опытные программисты сделали эту ошибку в тот или иной момент. Проблема в том, что next метод вызывается слишком много раз для «внешней» коллекции (мастей). Это вызывается во внутреннем цикле как для внешних, так и для внутренних коллекций, что неправильно. Чтобы исправить это, вы должны добавить переменную в Объем внешней петли для удержания костюма:

// Fixed, though a bit ugly
for (Iterator i = suits.iterator(); i.hasNext(); ) {
    Suit suit = (Suit) i.next();
    for (Iterator j = ranks.iterator(); j.hasNext(); )
        sortedDeck.add(new Card(suit, j.next()));
}

Так, что все это имеет отношение к конструкции for-each? Это специально для вложенная итерация! Полюбуйтесь:

for (Suit suit : suits)
   for (Rank rank : ranks)
       sortedDeck.add(new Card(suit, rank));

Если бы JSONObject.keys() было Iterable вместо Iterator, тогда для каждого - лучшее решение в вашем случае. Если вы считаете, что улучшение читабельности того стоит, вы можете, например, добавьте keys в Collection<String>, то есть Iterable.

Смежные вопросы

...