Pregunta ¿Cómo funciona la sentencia for mejorada para matrices y cómo obtener un iterador para una matriz?


Dado el siguiente fragmento de código:

int[] arr = {1, 2, 3};
for (int i : arr)
    System.out.println(i);

Tengo las siguientes preguntas:

  1. ¿Cómo funciona el bucle for-each anterior?
  2. ¿Cómo obtengo un iterador para una matriz en Java?
  3. ¿La matriz se convierte en una lista para obtener el iterador?

75
2017-10-12 08:25


origen


Respuestas:


Si quieres un Iterator sobre una matriz, puede usar una de las implementaciones directas en lugar de envolver la matriz en una List. Por ejemplo:

Colecciones de Apache Commons ArrayIterator

O bien, este, si desea usar genéricos:

com.Ostermiller.util.ArrayIterator

Tenga en cuenta que si desea tener un Iterator sobre tipos primitivos, no se puede, porque un tipo primitivo no puede ser un parámetro genérico. Por ejemplo, si quieres un Iterator<int>, tienes que usar un Iterator<Integer> en su lugar, lo que resultará en una gran cantidad de autoboxing y -unboxing si eso está respaldado por un int[].


55
2017-10-12 10:57



No, no hay conversión La JVM simplemente itera sobre la matriz usando un índice en el fondo.

Cita de Effective Java 2nd Ed., Artículo 46:

Tenga en cuenta que no hay penalización de rendimiento por usar   el bucle for-each, incluso para matrices. De hecho, puede ofrecer una ligera ventaja de rendimiento   sobre un bucle ordinario en algunas circunstancias, ya que calcula el límite de   el índice de matriz solo una vez.

Entonces no puedes obtener un Iterator para una matriz (a menos, por supuesto, convirtiéndolo en List primero).


49
2017-10-12 08:28



Arrays.asList (arr) .iterator ();

O escribe el tuyo, implementando la interfaz de ListIterator ...


33
2017-10-12 08:32



Google Librería Guavas colección proporciona tal función:

Iterator<String> it = Iterators.forArray(array);

Uno debería preferir la guayaba a la colección Apache (que parece estar abandonada).


31
2017-11-15 10:08



En Java 8:

Arrays.stream(arr).iterator();

14
2018-03-07 17:42



public class ArrayIterator<T> implements Iterator<T> {
  private T array[];
  private int pos = 0;

  public ArrayIterator(T anArray[]) {
    array = anArray;
  }

  public boolean hasNext() {
    return pos < array.length;
  }

  public T next() throws NoSuchElementException {
    if (hasNext())
      return array[pos++];
    else
      throw new NoSuchElementException();
  }

  public void remove() {
    throw new UnsupportedOperationException();
  }
}

10
2017-07-09 09:25



Estrictamente hablando, no se puede obtener un iterador de la matriz primitiva, porque Iterator.next () solo puede devolver un Objeto. Pero a través de la magia del autoboxing, puedes obtener el iterador usando el Arrays.asList () método.

Iterator<Integer> it = Arrays.asList(arr).iterator();


9
2017-10-12 08:36



No se puede obtener directamente un iterador para una matriz.

Pero puede usar una Lista, respaldada por su matriz, y obtener un ierator en esta lista. Para eso, tu matriz debe ser una Entero array (en lugar de una matriz int):

Integer[] arr={1,2,3};
List<Integer> arrAsList = Arrays.asList(arr);
Iterator<Integer> iter = arrAsList.iterator();

Nota: es solo teoría. Puede obtener un iterador como este, pero lo desanimo a hacerlo. Las interpretaciones no son buenas en comparación con una iteración directa en la matriz con la "sintaxis extendida".

Nota 2: una construcción de lista con este método no admite todos los métodos (ya que la lista está respaldada por la matriz que tiene un tamaño fijo). Por ejemplo, el método "eliminar" de su iterador dará como resultado una excepción.


5
2017-10-12 08:33