如何迭代SparseArray?
有没有一种方法来迭代Java SparseArray(Android版)? 我用sparsearray
很容易通过索引获取值。 我找不到一个。
似乎我find了解决方案。 我没有正确注意到keyAt(index)
函数。
所以我会去这样的事情:
for(int i = 0; i < sparseArray.size(); i++) { int key = sparseArray.keyAt(i); // get the object by the key. Object obj = sparseArray.get(key); }
如果你不关心关键字,那么可以在迭代稀疏数组的时候使用valueAt(int)
来直接访问这些值。
for(int i = 0, nsize = sparseArray.size(); i < nsize; i++) { Object obj = sparseArray.valueAt(i); }
你只需创建自己的ListIterator:
public final class SparseArrayIterator implements ListIterator { private final SparseArray 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 ListIterator iterate(SparseArray 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 ListIterator iterateAtKey(SparseArray 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 ListIterator iterateAt(SparseArray array, int location) { return new SparseArrayIterator (array, location); } private SparseArrayIterator(SparseArray 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(); } } }
使用上述循环从SparseArray
移除所有元素将导致Exception
。
为了避免这种情况请按照以下代码使用普通循环从SparseArray
删除所有元素
private void getValues(){ for(int i=0; i
简单如馅饼。 只要确保在实际执行循环之前获取数组大小。
for(int i = 0, arraySize= mySparseArray.size(); i < arraySize; i++) { Object obj = mySparseArray.get(/* int key = */ mySparseArray.keyAt(i)); }
希望这可以帮助。
这里是SparseArray
简单Iterator
和Iterable
实现:
public class SparseArrayIterator implements Iterator { private final SparseArray array; private int index; public SparseArrayIterator(SparseArray 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 implements Iterable { private final SparseArray sparseArray; public SparseArrayIterable(SparseArray sparseArray) { this.sparseArray = sparseArray; } @Override public Iterator iterator() { return new SparseArrayIterator<>(sparseArray); } }
如果你想迭代一个值,但也是一个关键:
public class SparseKeyValue { 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 implements Iterator> { private final SparseArray array; private int index; public SparseArrayKeyValueIterator(SparseArray array) { this.array = array; } @Override public boolean hasNext() { return array.size() > index; } @Override public SparseKeyValue next() { SparseKeyValue keyValue = new SparseKeyValue<>(array.keyAt(index), array.valueAt(index)); index++; return keyValue; } @Override public void remove() { array.removeAt(index); } } public class SparseArrayKeyValueIterable implements Iterable> { private final SparseArray sparseArray; public SparseArrayKeyValueIterable(SparseArray sparseArray) { this.sparseArray = sparseArray; } @Override public Iterator> iterator() { return new SparseArrayKeyValueIterator (sparseArray); } }
创建返回Iterable
和Iterable
实用程序方法很有用:
public abstract class SparseArrayUtils { public static Iterable> keyValueIterable(SparseArray sparseArray) { return new SparseArrayKeyValueIterable<>(sparseArray); } public static Iterable iterable(SparseArray sparseArray) { return new SparseArrayIterable<>(sparseArray); } }
现在你可以迭代SparseArray
:
SparseArray a = ...; for (String s: SparseArrayUtils.iterable(a)) { // ... } for (SparseKeyValue s: SparseArrayUtils.keyValueIterable(a)) { // ... }
对于使用Kotlin的人来说,实际上迭代SparseArray的最简单的方法是:使用Anko的Kotlin扩展!
只需拨打forEach { i, item -> }
答案是否定的,因为SparseArray
不提供它。 正如pst
所说的,这个东西不提供任何接口。
您可以从0 - size()
循环,并跳过返回null
,但是这是关于它。
正如我在我的评论中所述,如果你需要迭代使用一个Map
而不是一个SparseArray
。 例如,使用按键顺序迭代的TreeMap
。
TreeMap
被接受的答案有一些漏洞。 SparseArray的美妙之处在于它允许indeces中的空白。 所以,我们可以像SparseArray一样有两个地图…
(0,true) (250,true)
注意这里的大小是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); }
最好的方法是遍历数据集的大小,然后使用get()检查这些数组。 这里是一个适配器的例子,我允许批量删除项目。
for (int index = 0; index < mAdapter.getItemCount(); index++) { if (toDelete.get(index) == true) { long idOfItemToDelete = (allItems.get(index).getId()); mDbManager.markItemForDeletion(idOfItemToDelete); } }
我想最理想的是SparseArray系列将有一个getKeys()方法,但是它不。