2010-06-24 17 views
9

Tengo un problema con ArrayList. Estoy usando ArrayList como esto:ArrayList indexOf() devuelve el índice incorrecto?

private ArrayList<Playlist> mPlaylists; 

donde Playlist es una clase heredada de otra ArrayList. hago lo siguiente:

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

Más tarde, cuando se utiliza 'p' para obtener el índice de la lista:

int index = mPlaylists.indexOf(p); 

se devuelve un índice de '1', a pesar de que la inspección de la la lista muestra claramente que es el índice '4'.

¿Alguien sabe por qué esto falla? Gracias.

B.R. Morten

Editar: mismo problema sin indexOf(), usando equals():

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

Nueva edición: Esto funciona !:

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

de soluciones: Según lo sugerido, cambié la clase Playlist para no enher es de ArrayList, sino que guarda una instancia de forma privada. Resultó que solo tuve que implementar 4 métodos ArrayList.

Esto hace el truco; ¡Ahora indexOf() devuelve el objeto correcto!

¡Gracias a todos los contribuyentes!

+5

¿Qué hay en mPlaylists.get (1); ? ¿Ha anulado 'equals()' en 'Playlist' - ¿Hay algo raro allí? –

+0

¿La lista de reproducción prevalece sobre el índice de ArrayList? –

+1

Mi respuesta inicial es "lo que tienes no es lo que crees que tienes" seguido de "uno p piensa que es otro p (o no sabe lo que es)". –

Respuesta

7

Lo más probable es que su PlayList en mal estado con la aplicación por defecto ArrayList equals, porque la forma en indexOf es calculated a algo como:

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 

por lo tanto, usted está haciendo algo divertido con su método o su .equals son accidentalmente insertando otro elemento en la lista cuando crees que está al final.

EDITAR

Según su edición ... ver? Su método .equals() está roto.

considerar hacer una buena revisión y asegúrese de que se adhiere a la descripción definida en Object.equals

+0

+1: pásame por un minuto –

+0

Según tu nueva edición, estás haciendo una comparación de referencias que me hace pensar que realmente no estás heredando ArrayList.Parece que estás haciendo algo realmente extraño con esa clase 'PlayList' (como usar nombres de métodos en mayúsculas yiack ...) – OscarRyz

+0

Hehe, sí, pero al menos usando el nombre del método en mayúsculas, no olvidaré que esto es solo un método de prueba , con el fin de rastrear este problema :-) ¡Gracias! –

-1

no estoy seguro de por qué está teniendo este problema, pero creo que si yo fuera usted elegiría utilizar la lista genérica más reciente para crear su lista como esta:

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

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

No se puede crear una instancia de una lista ... no se pudo votar, sin votos hoy ;-) –

+0

El OP está usando la forma genérica - solo no la interfaz List, sino la implementación ArrayList. Aunque no está totalmente limpio, esto generalmente se considera correcto como miembro privado de una clase. Cuando lo escribe, simplemente no se compilará; no se puede crear una instancia de una lista; se trata de una interfaz. Ponga 'ArrayList' en el lado derecho de la tarea y todo estará bien. – mdma

+0

@Lauri - nunca temas, me quedan votos> :-) Russ - esto ni siquiera compilará y no responderá a la pregunta. –

1

Desde el API:

int indexOf(Object o):

Devuelve el índice de la primera aparición de la especificada elemento en esta lista, o -1 si esta lista no contiene el elemento. Más formalmente, devuelve el índice más bajo i tal que (o==null ? get(i)==null : o.equals(get(i))) o -1 si no existe dicho índice.

Así que la respuesta es que se debe redefinir .equals() en Playlist.

+0

No debería si él realmente está heredando 'ArrayList' porque ese método ya está anulado para esa clase. Por lo tanto, la sugerencia sería ** no ** anularla de nuevo (o hacerlo correctamente) – OscarRyz

+0

Hmm ... Entonces, ¿qué hice? ¿Heredar de ArrayList y no anular equals() debería funcionar? ... –

0

Puede haber muchas razones para este comportamiento:

1) Si varios elementos en un ArrayList son iguales (de acuerdo con método equals), entonces se devuelve el primera uno. Tal vez simplemente tienes múltiples objetos idénticos.

2) Su clase PlayList extiende ArrayList (no estoy seguro de que sea una buena idea). Por lo tanto, si no anuló el método de iguales, la comparación se basa solo en la secuencia de elementos. Por ejemplo, dos instancias de PlayList vacías se considerarán iguales.

3) Si sobrescribió iguales, verifique su implementación. Debe volverse verdadero para una comparación con la misma referencia, y en su caso no es así.

+0

Puedo ver su punto, pero como no anulé equals(), y hay algunos miembros de String más allá que difieren, ¿aún no esperaría que aparezcan como 'iguales'? –

+1

@Morten Priess: ¿Cuál fue el tipo de elementos dentro de PlayList? ¿Cuál fue la implementación equals() para este tipo? Si PlayList simplemente contiene objetos String, entonces no puedo explicar este comportamiento. –

Cuestiones relacionadas