Всегда индексируйте 0 при переборе списка

1

Я продолжаю получать первый объект в списке, когда я пытаюсь выполнить итерацию.

код:

@Override
        protected void onPostExecute(List<Location> locations) {
            // TODO Auto-generated method stub
            super.onPostExecute(locations);

            Log.d("Debug" , "List: " + locations.size() +  " markers");
            for (Location location : locations) {
                Log.d("Debug", "index of: " + locations.indexOf(location));
            }
        }

Распечатка говорит, что 200 маркеров в списке и распечатке индекса дают "0" 200 раз. Почему он не будет переходить к следующему объекту?

  • 3
    Вы реализовали equals () и hashCode () класса Location?
  • 0
    Все 200 объектов уникальны. Виноват
Показать ещё 1 комментарий
Теги:
list

4 ответа

2
Лучший ответ

Он правильно повторяет следующий объект:

.indexOf() просто рассматривает каждый объект в каждом индексе как .equals(location) == true для первого в индексе 0.

Доказательство:

Если вы добавили одно и то же Location 200 раз, а .equals() не будет правильно переопределено; например, если каждый экземпляр равен каждому другому экземпляру; вы вернетесь в первый матч.

В List.indexOf(Object o) Javadoc четко указано:

Возвращает индекс первого вхождения указанного элемента в этом списке или -1 если этот список не содержит этот элемент. Более формально возвращает наименьший индекс я такой, что (o==null? get(i)==null: o.equals(get(i))) или -1 если такого индекса нет.

Если .equals() думает, значит, вы получите первый матч.

В вашем случае индекс 0.

   public static void main(final String[] args)
    {
        final List<String> al = new ArrayList<String>(100);
        for (int i=0; i<100; i++) { al.add("Hello World!"); }
        for (final String s : al)
        {
            System.out.println(al.indexOf(s));
        }
    }

Распечатывается 0 100 раз.

Одно простое изменение

    for (int i=0; i<100; i++) { al.add(Integer.toString(i)); }

И вы видите, что код работает по назначению с уникальными объектами, которые рассматриваются правильно реализованным .equals()

  • 0
    Метод equals все еще может быть реализован правильно и получить этот результат. Программист должен решить, как два объекта Location считаются значимо равными.
  • 0
    @Rudi - это техническая составляющая, поскольку очевидно, что ФП считает все экземпляры уникальными и ожидает, что они будут уникальными. Учитывая это ожидание, .equals() не ведет себя правильно в их случае.
Показать ещё 2 комментария
1

Вероятно, потому что indexOf() возвращает первый индекс экземпляра объекта, который equals() объекту, который вы проверяете, и у вас должно быть много разных Location, которые считаются значимо равными. Это может быть связано с тем, что вы неправильно переопределили метод equals для Location или просто не рассматривали последствия вашего конкретного переопределения.

Взгляните на следующий пример, демонстрирующий вашу проблему, за исключением объектов String;

        ArrayList<String> als = new ArrayList<String>();
        als.add("a");
        als.add("b");
        als.add("c");
        als.add("d");
        als.add("e");

        for(String s : als) System.out.print(als.indexOf(s));

        als = new ArrayList<String>();
        als.add(new String("a"));
        als.add(new String("a"));
        als.add(new String("a"));
        als.add(new String("a"));
        als.add(new String("a"));
        System.out.println();
        for(String s : als) System.out.print(als.indexOf(s));

Это результаты;

01234
00000

В последние 5 выводимые 0 с, s String вы проверить массив для может быть второй или более String в массиве, но он оказывается по значению равно (как определено String классов equals() внахлест) в String в первый индекс, и поэтому он всегда будет возвращать 0. Попробуйте приведенный выше пример с массивом объектов вместо этого, и они никогда не считаются равными, если они не относятся к одному и тому же объекту в памяти.

0

Подтвердить метод равенства или проверить, что экземпляр не является нулевым. Это реализация метода на ArrayList, чтобы понять, почему.

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}
0

Обычно for (Location location: locations) выполняется indexOf() по объектам в списке мест. Когда вызывается indexOf() он использует equals и hashCode для поиска конкретного объекта, но я думаю, что вы не реализуете методы equals и hashCode класса Location. Попробуйте выполнить их и проверить.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню