如何迭代SparseArray?
有没有一种方法来迭代Java SparseArray(Android版)? 我用sparsearray
很容易通过索引获取值。 我找不到一个。
似乎我find了解决scheme。 我没有正确注意到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); }
你只需创build自己的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(); } } }
使用上述循环从SparseArray
移除所有元素将导致Exception
。
为了避免这种情况请按照以下代码使用普通循环从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; } }
简单如馅饼。 只要确保在实际执行循环之前获取数组大小。
for(int i = 0, arraySize= mySparseArray.size(); i < arraySize; i++) { Object obj = mySparseArray.get(/* int key = */ mySparseArray.keyAt(i)); }
希望这可以帮助。
这里是SparseArray<T>
简单Iterator<T>
和Iterable<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); } }
如果你想迭代一个值,但也是一个关键:
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); } }
创build返回Iterable<T>
和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); } }
现在你可以迭代SparseArray<T>
:
SparseArray<String> a = ...; for (String s: SparseArrayUtils.iterable(a)) { // ... } for (SparseKeyValue<String> s: SparseArrayUtils.keyValueIterable(a)) { // ... }
对于使用Kotlin的人来说,说实话,迭代SparseArray的最简单的方法是:使用Anko的Kotlin扩展!
只需拨打forEach { i, item -> }
答案是否定的,因为SparseArray
不提供它。 正如pst
所说的,这个东西不提供任何接口。
你可以从0 - size()
循环,并跳过返回null
,但这是关于它。
正如我在我的评论中所述,如果你需要迭代使用一个Map
而不是一个SparseArray
。 例如,使用按键顺序迭代的TreeMap
。
TreeMap<Integer, MyType>
被接受的答案有一些漏洞。 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()方法,但是它不。
- Android Studio – ADB错误 – “…设备未经授权。 请检查设备上的确认对话框。“
- 将您自己的SQLite数据库添加到Android应用程序
- 如何从adb中删除一个应用程序而不知道它的包名
- 当debugging代码块完成时,Android应用程序closures
- 在USBdebugging期间如何保持我的屏幕解锁?
- 获取已安装的应用程序
- 如何在android studio的外部库中添加一个jar
- google-services.json为不同的productFlavors
- 错误:ConnectionResult {statusCode = INTERNAL_ERROR,resolution = null}