recorrer for example java android

java - for - ¿Cómo iterar a través de SparseArray?



recorrer un linkedhashmap java (9)

Aquí están las implementaciones de SparseArray<T> e Iterable<T> para SparseArray<T> :

public class SparseArrayIterator<T> implements Iterator<T> { private final SparseArray<T> array; private int index; public SparseArrayIterator(SparseArray<T> array) { this.array = array; } @Override public boolean hasNext() { return array.size() > index; } @Override public T next() { return array.valueAt(index++); } @Override public void remove() { array.removeAt(index); } } public class SparseArrayIterable<T> implements Iterable<T> { private final SparseArray<T> sparseArray; public SparseArrayIterable(SparseArray<T> sparseArray) { this.sparseArray = sparseArray; } @Override public Iterator<T> iterator() { return new SparseArrayIterator<>(sparseArray); } }

Si desea iterar no solo un valor sino también una clave:

public class SparseKeyValue<T> { private final int key; private final T value; public SparseKeyValue(int key, T value) { this.key = key; this.value = value; } public int getKey() { return key; } public T getValue() { return value; } } public class SparseArrayKeyValueIterator<T> implements Iterator<SparseKeyValue<T>> { private final SparseArray<T> array; private int index; public SparseArrayKeyValueIterator(SparseArray<T> array) { this.array = array; } @Override public boolean hasNext() { return array.size() > index; } @Override public SparseKeyValue<T> next() { SparseKeyValue<T> keyValue = new SparseKeyValue<>(array.keyAt(index), array.valueAt(index)); index++; return keyValue; } @Override public void remove() { array.removeAt(index); } } public class SparseArrayKeyValueIterable<T> implements Iterable<SparseKeyValue<T>> { private final SparseArray<T> sparseArray; public SparseArrayKeyValueIterable(SparseArray<T> sparseArray) { this.sparseArray = sparseArray; } @Override public Iterator<SparseKeyValue<T>> iterator() { return new SparseArrayKeyValueIterator<T>(sparseArray); } }

Es útil crear métodos de utilidad que devuelven Iterable<T> e Iterable<SparseKeyValue<T>> :

public abstract class SparseArrayUtils { public static <T> Iterable<SparseKeyValue<T>> keyValueIterable(SparseArray<T> sparseArray) { return new SparseArrayKeyValueIterable<>(sparseArray); } public static <T> Iterable<T> iterable(SparseArray<T> sparseArray) { return new SparseArrayIterable<>(sparseArray); } }

Ahora puedes iterar SparseArray<T> :

SparseArray<String> a = ...; for (String s: SparseArrayUtils.iterable(a)) { // ... } for (SparseKeyValue<String> s: SparseArrayUtils.keyValueIterable(a)) { // ... }

¿Hay alguna forma de iterar sobre Java SparseArray (para Android)? Utilicé sparsearray para obtener fácilmente valores por índice. No pude encontrar uno.


La respuesta aceptada tiene algunos agujeros. La belleza de SparseArray es que permite espacios en los indeces. Entonces, podríamos tener dos mapas así, en un SparseArray ...

(0,true) (250,true)

Observe que el tamaño aquí sería 2. Si iteramos sobre el tamaño, solo obtendremos valores para los valores asignados al índice 0 y al índice 1. Por lo tanto, no se accede a la asignación con una clave de 250.

for(int i = 0; i < sparseArray.size(); i++) { int key = sparseArray.keyAt(i); // get the object by the key. Object obj = sparseArray.get(key); }

La mejor manera de hacer esto es iterar sobre el tamaño de su conjunto de datos, luego verificar esos índices con un get () en la matriz. Aquí hay un ejemplo con un adaptador donde estoy permitiendo la eliminación por lotes de elementos.

for (int index = 0; index < mAdapter.getItemCount(); index++) { if (toDelete.get(index) == true) { long idOfItemToDelete = (allItems.get(index).getId()); mDbManager.markItemForDeletion(idOfItemToDelete); } }

Creo que lo ideal sería que la familia SparseArray tuviera un método getKeys (), pero lamentablemente no lo tiene.


La respuesta es no porque SparseArray no lo proporciona. Como pst puso, esta cosa no proporciona ninguna interfaz.

Podría hacer un bucle entre 0 - size() y omitir valores que devuelven null , pero eso es todo.

Como SparseArray en mi comentario, si necesita iterar use un Map lugar de un SparseArray . Por ejemplo, use un TreeMap que se itera en orden por la clave.

TreeMap<Integer, MyType>


Ooor acaba de crear su propio ListIterator:

public final class SparseArrayIterator<E> implements ListIterator<E> { private final SparseArray<E> array; private int cursor; private boolean cursorNowhere; /** * @param array * to iterate over. * @return A ListIterator on the elements of the SparseArray. The elements * are iterated in the same order as they occur in the SparseArray. * {@link #nextIndex()} and {@link #previousIndex()} return a * SparseArray key, not an index! To get the index, call * {@link android.util.SparseArray#indexOfKey(int)}. */ public static <E> ListIterator<E> iterate(SparseArray<E> array) { return iterateAt(array, -1); } /** * @param array * to iterate over. * @param key * to start the iteration at. {@link android.util.SparseArray#indexOfKey(int)} * < 0 results in the same call as {@link #iterate(android.util.SparseArray)}. * @return A ListIterator on the elements of the SparseArray. The elements * are iterated in the same order as they occur in the SparseArray. * {@link #nextIndex()} and {@link #previousIndex()} return a * SparseArray key, not an index! To get the index, call * {@link android.util.SparseArray#indexOfKey(int)}. */ public static <E> ListIterator<E> iterateAtKey(SparseArray<E> array, int key) { return iterateAt(array, array.indexOfKey(key)); } /** * @param array * to iterate over. * @param location * to start the iteration at. Value < 0 results in the same call * as {@link #iterate(android.util.SparseArray)}. Value > * {@link android.util.SparseArray#size()} set to that size. * @return A ListIterator on the elements of the SparseArray. The elements * are iterated in the same order as they occur in the SparseArray. * {@link #nextIndex()} and {@link #previousIndex()} return a * SparseArray key, not an index! To get the index, call * {@link android.util.SparseArray#indexOfKey(int)}. */ public static <E> ListIterator<E> iterateAt(SparseArray<E> array, int location) { return new SparseArrayIterator<E>(array, location); } private SparseArrayIterator(SparseArray<E> array, int location) { this.array = array; if (location < 0) { cursor = -1; cursorNowhere = true; } else if (location < array.size()) { cursor = location; cursorNowhere = false; } else { cursor = array.size() - 1; cursorNowhere = true; } } @Override public boolean hasNext() { return cursor < array.size() - 1; } @Override public boolean hasPrevious() { return cursorNowhere && cursor >= 0 || cursor > 0; } @Override public int nextIndex() { if (hasNext()) { return array.keyAt(cursor + 1); } else { throw new NoSuchElementException(); } } @Override public int previousIndex() { if (hasPrevious()) { if (cursorNowhere) { return array.keyAt(cursor); } else { return array.keyAt(cursor - 1); } } else { throw new NoSuchElementException(); } } @Override public E next() { if (hasNext()) { if (cursorNowhere) { cursorNowhere = false; } cursor++; return array.valueAt(cursor); } else { throw new NoSuchElementException(); } } @Override public E previous() { if (hasPrevious()) { if (cursorNowhere) { cursorNowhere = false; } else { cursor--; } return array.valueAt(cursor); } else { throw new NoSuchElementException(); } } @Override public void add(E object) { throw new UnsupportedOperationException(); } @Override public void remove() { if (!cursorNowhere) { array.remove(array.keyAt(cursor)); cursorNowhere = true; cursor--; } else { throw new IllegalStateException(); } } @Override public void set(E object) { if (!cursorNowhere) { array.setValueAt(cursor, object); } else { throw new IllegalStateException(); } } }


Para eliminar todos los elementos de SparseArray utilizando los bucles anteriores, SparseArray a Exception .

Para evitar esto, siga el código de abajo para eliminar todos los elementos de SparseArray usando bucles normales

private void getValues(){ for(int i=0; i<sparseArray.size(); i++){ int key = sparseArray.keyAt(i); Log.d("Element at "+key, " is "+sparseArray.get(key)); sparseArray.remove(key); i=-1; } }


Para quienquiera que use Kotlin, honestamente, la forma más fácil de iterar sobre un SparseArray es: ¡Use la extensión Kotlin de Anko o Android KTX ! (crédito a Yazazzello por señalar Android KTX)

Simplemente llama a forEach { i, item -> }


Parece que encontré la solución. No había notado adecuadamente la función keyAt(index) .

Así que voy a ir con algo como esto:

for(int i = 0; i < sparseArray.size(); i++) { int key = sparseArray.keyAt(i); // get the object by the key. Object obj = sparseArray.get(key); }


Si no le importan las claves, entonces se puede usar valueAt(int) mientras se recorre la matriz dispersa para acceder directamente a los valores.

for(int i = 0, nsize = sparseArray.size(); i < nsize; i++) { Object obj = sparseArray.valueAt(i); }


Tan sencillo como el pastel. Solo asegúrese de obtener el tamaño de la matriz antes de realizar el bucle.

for(int i = 0, arraySize= mySparseArray.size(); i < arraySize; i++) { Object obj = mySparseArray.get(/* int key = */ mySparseArray.keyAt(i)); }

Espero que esto ayude.