que index array java arrays arraylist indexoutofboundsexception

java - que - ¿Cómo evitar ArrayIndexOutOfBoundsException o IndexOutOfBoundsException?



array index out of bounds exception java (2)

¿Qué es java.lang.ArrayIndexOutOfBoundsException / java.lang.IndexOutOfBoundsException?

El JavaDoc dice brevemente:

Lanzado para indicar que se ha accedido a una matriz con un índice ilegal. El índice es negativo o mayor o igual que el tamaño de la matriz.

¿Qué hace que suceda?

Esta excepción significa que ha intentado acceder a un índice en una matriz o lista respaldada por matriz y ese índice no existe.

Java usa 0 índices basados. Eso significa que todos los índices comienzan con 0 como el índice del primer elemento si contiene algún elemento.

El mensaje IndexOutOfBoundsException es muy explícito, generalmente toma la forma de:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

Donde Index es el índice que solicitó que no existe y Size es la longitud de la estructura en la que estaba indexando.

Como puede ver, un Size: 1 significa que el único índice válido es 0 y estaba preguntando qué estaba en el índice 1 .

Por ejemplo, si tiene una Array sin Array de objetos o tipos primitivos, los índices válidos son 0 a .length - 1 , en el siguiente ejemplo los índices válidos serían 0,1,2,3,

final String days[] { "Sunday", "Monday", "Tuesday" } System.out.println(days.length); // 3 System.out.println(days[0]); // Sunday System.out.println(days[1]); // Monday System.out.println(days[2]); // Tuesday System.out.println(days[3]); // java.lang.ArrayIndexOutOfBoundsException

Esto también se aplica a ArrayList , así como a cualquier otra clase de Collection que pueda estar respaldada por un Array y permitir el acceso directo al índice.

¿Cómo evitar la java.lang.ArrayIndexOutOfBoundsException / java.lang.IndexOutOfBoundsException ?

Al acceder directamente por índice:

Esto usa Guava para convertir la matriz primitiva sin procesar int[] en una ImmutableList<Integer> . Luego usa la clase Iterables para obtener de forma segura el valor en un índice particular y proporciona un valor predeterminado cuando ese índice no existe. Aquí elegí -1 para indicar un valor de índice no válido.

final List<Integer> toTen = ImmutableList.copyOf(Ints.asList(ints)); System.out.println(Iterables.get(toTen, 0, -1)); System.out.println(Iterables.get(toTen, 100, -1));

Si por alguna razón no puede usar Guava , es fácil usar su propia función para hacer lo mismo.

private static <T> T get(@Nonnull final Iterable<T> iterable, final int index, @Nonnull final T missing) { if (index < 0) { return missing; } if (iterable instanceof List) { final List<T> l = List.class.cast(iterable); return l.size() <= index ? l.get(index) : missing; } else { final Iterator<T> iterator = iterable.iterator(); for (int i = 0; iterator.hasNext(); i++) { final T o = iterator.next(); if (i == index) { return o; } } return missing; } }

Al iterar:

Estas son las formas idiomáticas de iterar sobre una Array sin Array si necesita conocer el índice y el valor:

Esto es susceptible a errores únicos que son las causas principales de una java.lang.ArrayIndexOutOfBoundsException :

Usando un bucle for / next tradicional:

final int ints[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; for (int i = 0; i < ints.length; i++) { System.out.format("index %d = %d", i, ints[i]); }

Usando un mejorado para / cada ciclo:

Aquí está la forma idiomática de iterar sobre una Array sin Array con el bucle for mejorado si no necesita conocer el índice real:

for (final int i : ints) { System.out.format("%d", i); System.out.println(); }

Usando un tipo seguro Iterator:

Aquí está la forma segura de iterar sobre una Array sin Array con el bucle for mejorado y rastrear el índice actual y evita la posibilidad de encontrar una java.lang.ArrayIndexOutOfBoundsException .

Esto usa Guava para convertir fácilmente el int[] en algo Iterable todo proyecto debería incluir.

final Iterator<Integer> it = Ints.asList(ints).iterator(); for (int i = 0; it.hasNext(); i++) { System.out.format("index %d = %d", i, it.next()); }

Si no puede usar Guava o su int[] es enorme, puede rodar su propio ImmutableIntArrayIterator como tal:

public class ImmutableIntArrayIterator implements Iterator<Integer> { private final int[] ba; private int currentIndex; public ImmutableIntArrayIterator(@Nonnull final int[] ba) { this.ba = ba; if (this.ba.length > 0) { this.currentIndex = 0; } else { currentIndex = -1; } } @Override public boolean hasNext() { return this.currentIndex >= 0 && this.currentIndex + 1 < this.ba.length; } @Override public Integer next() { this.currentIndex++; return this.ba[this.currentIndex]; } @Override public void remove() { throw new UnsupportedOperationException(); } }

Y use el mismo código que usaría con Guava.

Si debe tener el ordinal del artículo, la siguiente es la forma más segura de hacerlo.

// assume los is a list of Strings final Iterator<String> it = los.iterator(); for (int i = 0; it.hasNext(); i++) { System.out.format("index %d = %s", i, it.next()); }

Esta técnica funciona para todos los Iterables , no es un index persecución, pero le da la posición actual en la iteración incluso para cosas que no tienen un index nativo.

La forma mas segura:

La mejor manera es usar siempre ImmutableList<Integer> / Set / Maps from Guava también:

final List<Integer> ili = ImmutableList.copyOf(Ints.asList(ints)); final Iterator<Integer> iit = ili.iterator(); for (int i = 0; iit.hasNext(); i++) { System.out.format("index %d = %d", i, iit.next()); }

Resumen:

  1. El uso de Array procesar es difícil de trabajar y se debe evitar en la mayoría de los casos. Son susceptibles a errores ocasionales sutiles que han afectado a los nuevos programadores incluso desde los días de BASIC
  2. Las expresiones idiomáticas modernas de Java utilizan Collections seguras de tipo adecuado y evitan el uso de estructuras de Array sin Array si es posible.
  3. Immutable tipos Immutable se prefieren en casi todos los casos ahora.
  4. Guava es un kit de herramientas indispensable para el desarrollo moderno de Java.

Esta pregunta ya tiene una respuesta aquí:

Si su pregunta es , estoy obteniendo una java.lang.ArrayIndexOutOfBoundsException en mi código y no entiendo por qué está sucediendo. ¿Qué significa y cómo puedo evitarlo?

Se supone que es la recopilación de información Canonical más completa sobre este tema java.lang.ArrayIndexOutOfBoundsException , así como el java.lang.IndexOutOfBoundsException .

Hay muchas preguntas como esta y todas tienen respuestas vagas sin código, o en su mayoría son extremadamente específicas y localizadas para la pregunta en cuestión y no abordan la causa raíz, que es exactamente la misma en todos los casos.

Si ve uno que cae dentro de este caso general, en lugar de responderlo con más contenido especializado duplicado, márquelo como un duplicado de este.


En referencia a la documentación de Java Class ArrayIndexOutOfBoundsException , esta excepción se produce cuando intenta acceder a un elemento que es negativo o mayor que el tamaño de la matriz.

Considere el caso de que tenga 10 elementos en la matriz. Puede preguntarle al sistema cuál es el primero al décimo elemento dentro de la matriz. Si intenta preguntar cuál es el elemento -1 o el elemento número 100 de la matriz, Java responderá con la excepción anterior. Ahora tenga en cuenta que Array en Java está indexado 0. Por lo tanto, solo puede pasar un valor de índice de 0 a 9 inclusive. Cualquier número que no esté en este rango arrojará el error específico mencionado anteriormente.

Para evitar esta excepción, volvamos al concepto de CS101 y revisemos el concepto de bucle invariante. Esta es una condición para asegurarse de que la variable que utiliza para almacenar el índice debe cumplir con la condición particular.

Aquí hay un enlace a loop invariant: wikipedia> Loop invariant