2010-04-13 20 views
7

Estoy almacenando objetos enteros que representan un índice de objetos que deseo rastrear. Más adelante en mi código quiero verificar si el índice de un objeto en particular corresponde a uno de esos enteros que almacené anteriormente. Estoy haciendo esto mediante la creación de un ArrayList y la creación de un nuevo entero del índice de un bucle for:Comparar nuevos objetos enteros en ArrayList Pregunta

ArrayList<Integer> courseselectItems = new ArrayList(); 

//Find the course elements that are within a courseselect element and add their indicies to the ArrayList 
for(int i=0; i<numberElementsInNodeList; i++) { 
    if (nodeList.item(i).getParentNode().getNodeName().equals("courseselect")) { 
     courseselectItems.add(new Integer(i)); 
    } 
} 

entonces yo quiero comprobar posteriormente si el ArrayList contiene un índice en particular:

//Cycle through the namedNodeMap array to find each of the course codes 
for(int i=0; i<numberElementsInNodeList; i++) { 
    if(!courseselectItems.contains(new Integer(i))) { 
     //Do Stuff 
    } 
} 

Mi La pregunta es, cuando creo un nuevo Entero usando new Integer(i) ¿podré comparar números enteros usando ArrayList.contains()? Es decir, cuando creo un nuevo objeto usando new Integer(i), ¿será el mismo que el objeto Integer creado previamente si el valor int utilizado para crearlos es el mismo?

Espero no haber dejado esto muy claro. ¡Gracias por la ayuda!

+2

En una nota al margen, aquí hay algo que vale la pena saber sobre enteros y cadenas: http://www.devx.com/tips/Tip/42276 –

Respuesta

17

Sí, puede usar List.contains() que utiliza equals() y Integer lo admite cuando se compara con otras Integer s.

También, debido a auto-boxing simplemente puede escribir:

List<Integer> list = new ArrayList<Integer>(); 
... 
if (list.contains(37)) { // auto-boxed to Integer 
    ... 
} 

Vale la pena mencionar que:

List list = new ArrayList(); 
list.add(new Integer(37)); 
if (list.contains(new Long(37)) { 
    ... 
} 

se siempre retorno false porque un Integer no es un Long. Esto hace tropezar a la mayoría de las personas en algún momento.

Por último, tratar de hacer que sus variables que son colecciones de Java del tipo de interfaz no es el tipo de cemento, así:

List<Integer> courseselectItems = new ArrayList(); 

no

ArrayList<Integer> courseselectItems = new ArrayList(); 
+0

¡Gracias! ¿Hay alguna razón en particular por la que quiero hacer que mis variables sean del tipo de interfaz y no del tipo concreto? – ericso

+1

@thechiman el tipo concreto es un detalle de implementación. * En términos generales, los parámetros *, las variables locales y los miembros de la clase deben ser la interfaz para que no esté vinculado a una implementación en particular. Le permite, por ejemplo, agregar una implementación de 'Lista' personalizada en algún momento posterior, etc. – cletus

+0

Esto no es tan importante si la' Lista' es completamente privada para la clase, visible en ninguna otra parte. Pero si lo está exponiendo de alguna manera (por ejemplo, la clase que contiene la lista tiene un método para regresar la lista), entonces definitivamente debe devolverlo como 'Lista' y no como' ArrayList'. Puede decidir más adelante, por ejemplo, que 'LinkedList' es una implementación más apropiada. –

1

respuesta corta es sí, usted debería ser capaz de do ArrayList.contains(new Integer(14)), por ejemplo, para ver si 14 está en la lista. El motivo es que Integer anula el método equals para compararse correctamente con otras instancias con el mismo valor.

1

Sí lo hará, porque List.contains() utiliza el método equals() del objeto que se va a comparar. Y Integer.equals() compara el valor entero.

0

Sí, se produce un boxeo automático, pero esto da como resultado una penalización en el rendimiento. No está claro en su ejemplo por qué querría resolver el problema de esta manera.

Además, debido al boxeo, crear la clase Integer a mano es superfluo.

1

Como mencionó Cletus y DJ, su enfoque funcionará.

no sé el contexto de su código, pero si no se preocupan por los índices particulares, considere el siguiente estilo también:

List<Node> courseSelectNodes = new ArrayList<Node>(); 

//Find the course elements that are within a courseselect element 
//and add them to the ArrayList 
for(Node node : numberElementsInNodeList) { 
    if (node.getParentNode().getNodeName().equals("courseselect")) { 
     courseSelectNodes.add(node); 
    } 
} 

// Do stuff with courseSelectNodes 
for(Node node : courseSelectNodes) { 
    //Do Stuff 
} 
+0

Me gusta esto también. Podría cambiar mi código para hacer esto. ¡Gracias! – ericso

+0

Terminé cambiando mi código para hacer algo similar a esto. ¡Gracias! – ericso

1

Estoy poniendo mi respuesta en forma de una prueba (pasajera), como un ejemplo de cómo puede investigar esto usted mismo. No para disuadirlo de usar SO, es genial, solo para tratar de promocionar characterization tests.

import java.util.ArrayList; 
import junit.framework.TestCase; 

public class ContainsTest extends TestCase { 
    public void testContains() throws Exception { 
     ArrayList<Integer> list = new ArrayList<Integer>(); 
     assertFalse(list.contains(new Integer(17))); 
     list.add(new Integer(17)); 
     assertTrue(list.contains(new Integer(17))); 
    } 
} 
+0

Sí, ahora que lo pienso, podría haberlo probado fácilmente. Heh, me siento tonto. Gracias. :) – ericso

4

Mi pregunta es, cuando se crea un nuevo entero mediante el uso de new Integer (i) tendrá que ser capaz de comparar números enteros utilizando ArrayList.contains()? Es decir, cuando creo un nuevo objeto usando un nuevo Entero (i), ¿será el mismo que el objeto Entero creado anteriormente si el valor int utilizado para crearlos es el mismo?

La respuesta corta es sí.

La respuesta larga es ...

Es decir, cuando se crea un nuevo objeto utilizando new Integer (i), habrá que ser el mismo que el creado previamente objeto Integer si el int valor utilizado para crearlos son los mismos?

supongo que te refieres "... ¿será el mismo ejemplo como ..."? La respuesta a esto es no - llamando al new siempre creará una instancia distinta separada de la instancia anterior, incluso si los parámetros del constructor son idénticos.

Sin embargo, a pesar de tener separada identidad, estos dos objetos tendrán valor equivalente, es decir .equals llamando al() entre ellos volverán cierto.

Collection.contains()

Resulta que tener instancias independientes de valor equivalente (.equals() devuelve verdadero) está bien. El método .contains() se encuentra en la interfaz Collection. La descripción Javadoc para .contains() dice:

http://java.sun.com/javase/6/docs/api/java/util/Collection.html#contains(java.lang.Object)

boolean contains (Object o)

devuelve verdadero si esta colección contiene el elemento especificado. Más formalmente, devuelve verdadero si y sólo si esta colección contiene al menos un elemento de tal que e (O == null e == null :? o.equals (e)).

Por lo tanto, se hará lo que usted desea.

Estructura de Datos

También debe considerar si usted tiene la estructura de datos de la derecha.

¿La lista es únicamente sobre contención? es el orden importante? ¿Te importan los duplicados? Dado que una lista es un pedido, usar una lista puede implicar que su código se preocupa por ordenar. O que necesita mantener duplicados en la estructura de datos.

Sin embargo, si el orden no es importante, si no quieren o no tendrá duplicados, y si realmente sólo se utiliza esta estructura de datos para comprobar si contiene un valor específico, entonces es posible que desee considerar si debe usar un Set en su lugar.

Cuestiones relacionadas