ArrayList indexOf () возвращает неверный индекс? - PullRequest
9 голосов
/ 25 июня 2010

У меня проблема с ArrayList. Я использую ArrayList, как это:

private ArrayList<Playlist> mPlaylists;

где Playlist - это класс, унаследованный от другого ArrayList. Я делаю следующее:

p = new Playlist(...some parameters...);
mPlaylists.add(p);

Позже, когда я использую 'p', чтобы получить индекс в списке:

int index = mPlaylists.indexOf(p);

возвращается индекс '1', хотя проверка списка ясно показывает, что это индекс '4'.

Кто-нибудь знает, почему это не удается? Спасибо.

B.R. Morten

Edit: Та же проблема без indexOf (), используя equals ():

private int GetIndex(Playlist playlist) {
    for (int i = 0; i < mPlaylists.size(); i++) {
        if (mPlaylists.get(i).equals(playlist)) {
            return i;
        }
    }
    return -1;
}

Новое редактирование: Это работает!:

private int getIndex(Playlist playlist) {
    for (int i = 0; i < mPlaylists.size(); i++) {
        if (mPlaylists.get(i) == playlist) {
            return i;
        }
    }
    return -1;
}

Решение: Как и предполагалось, я изменил класс Playlist, чтобы он не наследовал от ArrayList, а скорее оставил экземпляр в частном порядке. Оказалось, что мне нужно было реализовать только 4 метода ArrayList.

Это делает трюк; Теперь indexOf () возвращает правильный объект!

Спасибо всем участникам!

Ответы [ 4 ]

7 голосов
/ 25 июня 2010

Скорее всего, ваша PlayList испорчена с реализацией ArrayList equals по умолчанию, потому что indexOf вычисляет , вычисляемое как:

indexOf(Object o) 
   if( o == null ) then iterate until null is found and return that index
   if( o != null ) iterate until o.equals( array[i] ) is found and return taht index
   else return -1 
end

Итак, вы делаете что-то смешное с вашим методом .equals или случайно вставляете другой элемент в список, когда думаете, что он в конце.

EDIT

Согласно вашему редактированию ... видите? Ваш .equals() метод не работает.

Попробуйте сделать хороший обзор и убедитесь, что он соответствует описанию, определенному в Object.equals

1 голос
/ 25 июня 2010

Из API :

int indexOf(Object o)

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

Таким образом, ответ таков: вам нужно переопределить .equals() в Playlist.

0 голосов
/ 25 июня 2010

Причин такого поведения может быть много:

1) Если несколько элементов в ArrayList равны (в соответствии с методом equals), то возвращается first one. Может быть, у вас просто есть несколько одинаковых объектов.

2) Ваш класс PlayList расширяет ArrayList (я не уверен, что это хорошая идея). Поэтому, если вы не переопределили метод equals, сравнение основано только на последовательности элементов. Например, любые два пустых экземпляра PlayList будут считаться равными.

3) Если вы DID переопределяете равно, проверьте вашу реализацию. Он должен возвращать true для сравнения с той же ссылкой, а в вашем случае - нет.

0 голосов
/ 25 июня 2010

Я не уверен, почему у вас возникла эта проблема, но я думаю, что на вашем месте я бы выбрал более новый Общий список для создания вашего списка следующим образом:

List<Playlist> mPlaylists = new List<Playlist>();

p = new Playlist(<some parameters>);
mPlaylists.Add(p);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...