2010-06-24 3 views
9

J'ai un problème avec ArrayList. J'utilise ArrayList comme ceci:ArrayList indexOf() renvoie un mauvais index?

private ArrayList<Playlist> mPlaylists; 

où Playlist est une classe héritée d'une autre ArrayList. Je fais ce qui suit:

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

Plus tard, quand j'utilise 'p' pour obtenir l'index dans la liste:

int index = mPlaylists.indexOf(p); 

un indice de '1' est retourné, même si l'inspection de la liste montre clairement que c'est l'index '4'.

Est-ce que quelqu'un sait pourquoi cela a échoué? Merci.

B.R. Morten

Modifier: Même problème sans indexOf(), en utilisant equals():

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

Nouvelle édition: Cela fonctionne !:

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

Solution: Comme suggéré, j'ai changé la classe Playlist pour ne pas entrer à partir de ArrayList, mais en gardant une instance en privé. Il s'est avéré que je devais seulement implémenter 4 méthodes ArrayList.

Cela fait l'affaire; Maintenant indexOf() retourne l'objet correct!

Merci à tous les contributeurs!

+5

Qu'est-ce que mPlaylists.get (1); ? Avez-vous remplacé 'equals()' dans 'Playlist' - quelque chose de funky là-bas? –

+0

La liste de lecture remplace-t-elle l'indexOf de ArrayList? –

+1

Ma réponse initiale est "le p que vous avez n'est pas le p que vous pensez avoir" suivi par "un p pense que c'est un autre p (ou ne sait pas ce que c'est)". –

Répondre

7

Très probablement votre PlayList foiré avec la valeur par défaut ArrayList equals mise en œuvre, car la façon dont indexOf est calculated à quelque chose comme:

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 

Alors, vous faites quelque chose de drôle avec votre méthode equals ou vous êtes accidentellement insérant un autre élément dans la liste quand vous pensez qu'il est à la fin.

EDIT

Selon votre édition ... voir? Votre méthode .equals() est cassée.

Pensez à faire un bon examen et assurez-vous qu'il adhère à la description définie dans Object.equals

+0

+1: Me battre d'une minute –

+0

Selon votre nouvelle édition, vous faites des comparaisons de références qui me font penser que vous n'héritez pas du tout ArrayList.On dirait que vous faites quelque chose de vraiment étrange avec cette classe 'PlayList' (comme l'utilisation des noms de méthodes en majuscules yiack ...) – OscarRyz

+0

Hehe, oui - mais au moins en utilisant le nom de la méthode majuscule, je n'oublierai pas que c'est seulement une méthode de test , dans le but de traquer ce problème :-) Merci! –

-1

Je ne sais pas pourquoi vous rencontrez ce problème, mais je pense que si je vous je choisis d'utiliser la nouvelle liste générique pour créer votre liste comme ceci:

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

p = new Playlist(<some parameters>); 
mPlaylists.Add(p); 
+0

Impossible d'instancier une liste .. ne peut pas voter vers le bas cependant, hors des votes aujourd'hui ;-) –

+0

L'OP utilise le formulaire générique - juste pas l'interface List, mais l'implémentation ArrayList. Bien que pas totalement propre, cela est généralement considéré comme un membre privé d'une classe. Lorsque vous avez écrit simplement ne compilera pas - vous ne pouvez pas instancier une liste - c'est une interface. Mettez 'ArrayList' sur le côté droit de la tâche et tout ira bien. – mdma

+0

@Lauri - ne crains jamais, j'ai des votes à gauche> :-) Russ - ce ne sera même pas compiler, et ne répond pas à la question. –

1

De l'API:

int indexOf(Object o):

Renvoie l'index de la première occurrence du spécifié élément dans cette liste, ou -1 si cette liste ne contient pas l'élément. Plus formellement, renvoie l'indice le plus bas i tel que (o==null ? get(i)==null : o.equals(get(i))), ou -1 s'il n'y a pas un tel index.

La réponse est donc que vous devez remplacer .equals() dans Playlist.

+0

Il ne devrait pas s'il hérite vraiment de 'ArrayList' parce que cette méthode est déjà remplacé pour cette classe. Donc, la suggestion serait ** pas ** de le remplacer à nouveau (ou de le faire correctement) – OscarRyz

+0

Hmm ... Donc ce que j'ai fait; Hériter de ArrayList et ne pas surcharger equals() devrait fonctionner? ... –

0

Il peut y avoir de nombreuses raisons de ce comportement:

1) Si plusieurs éléments dans un ArrayList sont égaux (selon méthode equals), le premier on est retourné. Peut-être que vous avez simplement plusieurs objets identiques.

2) Votre classe PlayList étend ArrayList (je ne suis pas sûr que ce soit une bonne idée). Par conséquent, si vous n'avez pas remplacé la méthode equals, la comparaison est basée uniquement sur la séquence d'éléments. Par exemple, deux instances PlayList vides seront considérées égales.

3) Si vous avez DID override, vérifiez votre implémentation. Il doit retourner vrai pour une comparaison avec la même référence, et dans votre cas ce n'est pas le cas.

+0

Je vois ce que vous voulez dire, mais comme je n'ai pas écrasé equals(), et qu'il y a des membres de String qui sont différents, je ne m'attendrais toujours pas à ce qu'ils soient égaux? –

+1

@Morten Priess: Quel était le type d'éléments dans PlayList? Quelle était l'implémentation de equals() pour ce type? Si PlayList contient simplement des objets String, je ne peux pas expliquer ce comportement. –

Questions connexes