java: ArrayList - ¿cómo puedo comprobar si existe un índice?


111

Estoy usando ArrayList<String>y agrego datos en índices específicos, ¿cómo puedo verificar si existe un índice específico?

¿Debería simplemente get()comprobar el valor? ¿O debería esperar una excepción? ¿Hay otra manera?

Actualizar

Gracias por sus respuestas, pero debido a que solo agrego cosas en índices específicos, la longitud de la lista no me mostrará cuáles están disponibles.


2
Eche un vistazo a un conjunto que tal vez sea más adecuado para lo que necesita.
Paul Whelan

3
Entonces tendrás que get()comprobarlo null, pero no confíes en las excepciones. Considere usar java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.htmlHashTable en su lugar
Amarghosh

¡¡increíble!! Usaré HashTable gracias
ufk

Respuestas:


158

El método arrayList.size() devuelve el número de elementos de la lista, por lo que si el índice es mayor o igual que size(), no existe.

if(index >= myList.size()){
  //index not exists
}else{
 // index exists
}

10
Eso debería ser "mayor o igual que size()" ya que es un índice de base cero.
McDowell

1
También vale la pena mencionar que para hacer esto atómico probablemente debería realizar la verificación de tamaño () y la búsqueda basada en el índice condicional correspondiente mientras bloquea la lista.
Adamski

3
tenga en cuenta que marqué esta respuesta como correcta porque el propietario (Amarghosh) respondió a mi pregunta en un comentario a mi pregunta. HashTable se adaptará a mis necesidades mucho mejor.
ufk

¿Qué pasa si está configurando elementos en la lista de matrices con el ID del elemento? ex. mylist.set (1, item1); mylist.set (3, item3); // omitiendo 2 ¿Supongo que HashMap es más adecuado para ese escenario?
yeahman

esto no me satisface del todo ... si quiero hacer algo en la lista si el índice ya está allí, pero de lo contrario, prepararlo ... con una nueva lista en la que comenzaré index = 0y mi list.size() == 0también. así que la primera vez que lo verifique será cierto y prepararé la lista para hacer cosas. pero la próxima vez en ese índice, mi índice seguirá estando index = 0y ahora estoy reinicializando ese elemento en la lista cuando se suponía que debía estar haciendo cosas. El primer pensamiento es &&una segunda condición como list.get(index) == nullpero que no funciona es por eso que hay preguntas como esta
roberto tomás

69

Si bien recibió una docena de sugerencias sobre cómo usar el tamaño de su lista, que funciona para listas con entradas lineales, nadie pareció leer su pregunta.

Si agrega entradas manualmente en diferentes índices, ninguna de estas sugerencias funcionará, ya que debe verificar un índice específico.

Usar if (list.get (index) == null) tampoco funcionará, ya que get () genera una excepción en lugar de devolver null.

Prueba esto:

try {
    list.get( index );
} catch ( IndexOutOfBoundsException e ) {
    list.add( index, new Object() );
}

Aquí se agrega una nueva entrada si el índice no existe. Puede modificarlo para hacer algo diferente.


2
Gracias, necesitaba esta técnica para probar unitariamente si existen índices de matriz.
Noumenon

11
Recuerde que debe evitar el uso try/catchpara este tipo de trabajo, ralentizará su programa en un 50% o tal vez más ... la comprobación de errores se agrega como una correa a su código existente para ralentizarlo ... mejor evitarlo en áreas críticas. Verificar lengthen este caso es lo mejor que puede hacer, ya indexque siempre será menor que lo anterior length, los viejos se indexcambiarán y se convertirán en nuevos indexsi los usa remove, por eso la verificación de reglas para lengthsiempre funcionará.
Habló el

1
@SSpoke ... Aunque estoy de acuerdo, try / catch está lejos de ser una "buena" respuesta; solucionará el problema cuando la lista sea escasa. Prefiero la sugerencia de usar una matriz: Object [] ary; debajo o un hash.
será el

12

Esto es lo que necesitas ...

public boolean indexExists(final List list, final int index) {
    return index >= 0 && index < list.size();
}

¿Por qué no usar una matriz vieja y simple? El acceso indexado a una lista es un olor a código, creo.


3
No siempre, ya que es posible que desee que ArrayList crezca con el tiempo y que una matriz no puede hacerlo.
Coyote 21 de

7

Por lo general, solo verifico si el índice es menor que el tamaño de la matriz

if (index < list.size()) {
    ...
}

Si también le preocupa que el índice sea un valor negativo, use lo siguiente

if (index >= 0 && index < list.size()) {
    ...
}

1
¿Cómo aporta esto algún valor sobre la respuesta aceptada de hace varios años?
Basil Bourque

2
Supongo que en su opinión no aporta ningún valor, pero vi un comentario de roberto tomás sobre la respuesta aceptada, asumiendo que no entendió del todo la respuesta aceptada. compruébalo "con una nueva lista voy a empezar en index = 0 y mi list.size () == 0 también. así que la primera vez que verifique será cierto" Decidí publicar una respuesta separada para ayudar cualquier confusión futura.
AamirR

6

Con respecto a su actualización (que probablemente debería ser otra pregunta). Debe usar una matriz de estos objetos en lugar de una ArrayList, por lo que simplemente puede verificar el valor para nulo:

Object[] array = new Object[MAX_ENTRIES];
..
if ( array[ 8 ] == null ) {
   // not available
}
else {
   // do something
}

Mejores prácticas

Si no tiene cientos de entradas en su matriz, debería considerar organizarla como una clase para deshacerse de los números mágicos 3,8, etc.

Controlar el flujo mediante la excepción es una mala práctica.


1
Si la matriz [8] no existe, encontrará ArrayIndexOutOfBoundException.
Nitesh Kumar Anand


3

Puede verificar el tamaño de un ArrayListusando el size()método. Esto devolverá el índice máximo +1


2

una forma sencilla de hacer esto:

try {
  list.get( index ); 
} 
catch ( IndexOutOfBoundsException e ) {
  if(list.isEmpty() || index >= list.size()){
    // Adding new item to list.
  }
}

1

Prueba rápida y sucia para determinar si existe un índice o no. en su implementación reemplazar lista Con su lista que está probando.

public boolean hasIndex(int index){
    if(index < list.size())
        return true;
    return false;
}

o para ArrayLists bidimensionales ...

public boolean hasRow(int row){
    if(row < _matrix.size())
        return true;
    return false;
}

1
List no .lengthlo tiene, list.size()pero no es gran cosa. Me equivoco así todo el tiempo, jaja, confío en el compilador para guiarme en eso. Probablemente estaba pensando en matrices primitivas
SSpoke

1
Gracias por captar eso. La cardinalidad de los contenedores puede ser fácil de olvidar.
t3dodson

0

Si su índice es menor que el tamaño de su lista, entonces existe, posiblemente con nullvalor. Si el índice es más grande, puede llamar ensureCapacity() para poder usar ese índice.

Si desea verificar si un valor en su índice es nullo no, llameget()


1
Llamar a secureCapacity (int) no aumentará el tamaño de la Lista, solo la capacidad; es decir, "tamaño potencial", por lo que las búsquedas de índices fuera de los límites aún fallarían.
Adamski

Además, ¿por qué llamar a asegurarCapacidad (int)? Podría ser una operación increíblemente costosa si, por ejemplo, el tamaño actual de la lista es 5 y desea determinar el valor del artículo #: 100,000,000.
Adamski

Quise decir que siempre existen índices menores que size (), los que son> = size () no y no se pueden usar (== call set ()) hasta que la lista sea lo suficientemente grande. Llamar a secureCapacity no es suficiente, uno necesita cambiar el tamaño agregando elementos.
Dmitry

Explicación incorrecta acerca de lo que garantiza la capacidad (int) en realidad. No hace nada con el tamaño de ArrayList.
Mohsen

0

Puede verificar el tamaño de la matriz.

package sojava;
import java.util.ArrayList;

public class Main {
    public static Object get(ArrayList list, int index) {
        if (list.size() > index) { return list.get(index); }
        return null;
    }

    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(""); list.add(""); list.add("");        
        System.out.println(get(list, 4));
        // prints 'null'
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.