This article is participating in the Java Theme Month – Java Debug Notes Event, see the event link for details
The problem
Is there a way to traverse Java SparseArray (for Android), I used SparseArray to easily get the corresponding value through the index, but did not find a way to traverse.
answer
Answer 1
It looks like I’ve found a solution. I didn’t notice the keyAt(index) method correctly, so I’ll do this:
for(int i = 0; i < sparseArray.size(); i++) {
int key = sparseArray.keyAt(i);
// Get the object by key
Object obj = sparseArray.get(key);
}
Copy the code
Answer 2
Maybe you just need to create your own 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(a) {
return cursor < array.size() - 1;
}
@Override
public boolean hasPrevious(a) {
return cursorNowhere && cursor >= 0 || cursor > 0;
}
@Override
public int nextIndex(a) {
if (hasNext()) {
return array.keyAt(cursor + 1);
} else {
throw newNoSuchElementException(); }}@Override
public int previousIndex(a) {
if (hasPrevious()) {
if (cursorNowhere) {
return array.keyAt(cursor);
} else {
return array.keyAt(cursor - 1); }}else {
throw newNoSuchElementException(); }}@Override
public E next(a) {
if (hasNext()) {
if (cursorNowhere) {
cursorNowhere = false;
}
cursor++;
return array.valueAt(cursor);
} else {
throw newNoSuchElementException(); }}@Override
public E previous(a) {
if (hasPrevious()) {
if (cursorNowhere) {
cursorNowhere = false;
} else {
cursor--;
}
return array.valueAt(cursor);
} else {
throw newNoSuchElementException(); }}@Override
public void add(E object) {
throw new UnsupportedOperationException();
}
@Override
public void remove(a) {
if(! cursorNowhere) { array.remove(array.keyAt(cursor)); cursorNowhere =true;
cursor--;
} else {
throw newIllegalStateException(); }}@Override
public void set(E object) {
if(! cursorNowhere) { array.setValueAt(cursor, object); }else {
throw newIllegalStateException(); }}}Copy the code
Answer 3
Honestly, no matter who uses Kotlin, by far the easiest way to traverse SparseArray is to use the Kotlin extension (Anko or Android KTX).
Just call forEach {I, item ->}.
provenance
Stack Overflow: How to iterate through SparseArray?