本文翻译自:How to iterate through SparseArray?
Is there a way to iterate over Java SparseArray (for Android) ? 有没有办法迭代Java SparseArray(适用于Android)? I used sparsearray
to easily get values by index. 我使用sparsearray
轻松地通过索引获取值。 I could not find one. 我找不到一个。
#1楼
参考:https://stackoom.com/question/XYxX/如何遍历SparseArray
#2楼
If you don't care about the keys, then valueAt(int)
can be used to while iterating through the sparse array to access the values directly. 如果您不关心键,则可以使用valueAt(int)
迭代稀疏数组以直接访问值。
for(int i = 0, nsize = sparseArray.size(); i < nsize; i++) {
Object obj = sparseArray.valueAt(i);
}
#3楼
Ooor you just create your own ListIterator: 您只需创建自己的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();
}
}
}
#4楼
The accepted answer has some holes in it. 接受的答案中有一些漏洞。 The beauty of the SparseArray is that it allows gaps in the indeces. SparseArray的优点在于它允许空隙中的间隙。 So, we could have two maps like so, in a SparseArray... 所以,我们可以在SparseArray中有两个这样的地图......
(0,true)
(250,true)
Notice the size here would be 2. If we iterate over size, we will only get values for the values mapped to index 0 and index 1. So the mapping with a key of 250 is not accessed. 请注意,此处的大小为2.如果我们迭代大小,我们将只获取映射到索引0和索引1的值的值。因此,不访问具有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);
}
The best way to do this is to iterate over the size of your data set, then check those indeces with a get() on the array. 执行此操作的最佳方法是迭代数据集的大小,然后使用数组上的get()检查这些indeces。 Here is an example with an adapter where I am allowing batch delete of items. 这是一个适配器的例子,我允许批量删除项目。
for (int index = 0; index < mAdapter.getItemCount(); index++) {
if (toDelete.get(index) == true) {
long idOfItemToDelete = (allItems.get(index).getId());
mDbManager.markItemForDeletion(idOfItemToDelete);
}
}
I think ideally the SparseArray family would have a getKeys() method, but alas it does not. 我认为理想情况下SparseArray系列会有一个getKeys()方法,但它没有。
#5楼
Simple as Pie. 像饼一样简单。 Just make sure you fetch array size before actually performing the loop. 只需确保在实际执行循环之前获取数组大小。
for(int i = 0, arraySize= mySparseArray.size(); i < arraySize; i++) {
Object obj = mySparseArray.get(/* int key = */ mySparseArray.keyAt(i));
}
Hope this helps. 希望这可以帮助。
#6楼
For removing all the elements from SparseArray
using the above looping leads to Exception
. 使用上面的循环导致Exception
从SparseArray
删除所有元素。
To avoid this Follow the below code to remove all the elements from SparseArray
using normal loops 要避免这种情况请按照以下代码使用普通循环从SparseArray
删除所有元素
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;
}
}