java如何遍历数组,java - 如何遍历SparseArray?

java - 如何遍历SparseArray?

有没有办法迭代Java SparseArray(适用于Android)? 我使用sparsearray轻松获取索引值。 我找不到一个。

Ruzanna asked 2019-02-04T11:44:50Z

9个解决方案

482 votes

似乎我找到了解决方案。 我没有正确注意到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);

}

Ruzanna answered 2019-02-04T11:45:04Z

167 votes

如果您不关心密钥,则可以使用valueAt(int)迭代稀疏数组以直接访问值。

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

Object obj = sparseArray.valueAt(i);

}

Pogo Lin answered 2019-02-04T11:45:26Z

16 votes

您只需创建自己的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();

}

}

}

0101100101 answered 2019-02-04T11:45:48Z

9 votes

像饼一样简单。 只需确保在实际执行循环之前获取数组大小。

for(int i = 0, arraySize= mySparseArray.size(); i < arraySize; i++) {

Object obj = mySparseArray.get(/* int key = */ mySparseArray.keyAt(i));

}

希望这可以帮助。

Pascal answered 2019-02-04T11:46:11Z

7 votes

使用上面的循环导致从SparseArray删除所有元素到Exception。

要避免这种情况请按照以下代码使用普通循环从SparseArray中删除所有元素

private void getValues(){

for(int i=0; i

int key = sparseArray.keyAt(i);

Log.d("Element at "+key, " is "+sparseArray.get(key));

sparseArray.remove(key);

i=-1;

}

}

Sackurise answered 2019-02-04T11:46:39Z

6 votes

无论谁使用Kotlin,老实说,迭代SparseArray的最简单方法是:使用Anko或Android KTX的Kotlin扩展! (感谢Yazazzello指出Android KTX)

请致电forEach { i, item -> }

0101100101 answered 2019-02-04T11:47:08Z

4 votes

这里是SparseArray和Iterable> SparseArray的简单实现:

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);

}

}

创建返回SparseArray和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)) {

// ...

}

mixel answered 2019-02-04T11:47:49Z

-5 votes

答案是否定的,因为Map不提供它。 正如SparseArray所说,这个东西不提供任何接口。

您可以从Map循环并跳过返回SparseArray的值,但这是关于它的。

正如我在评论中所述,如果您需要迭代使用Map而不是SparseArray。例如,使用TreeMap按键顺序迭代。

TreeMap

John B answered 2019-02-04T11:48:24Z

-6 votes

接受的答案中有一些漏洞。 SparseArray的优点在于它允许空隙中的间隙。 所以,我们可以在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()检查这些indeces。 这是一个适配器的例子,我允许批量删除项目。

for (int index = 0; index < mAdapter.getItemCount(); index++) {

if (toDelete.get(index) == true) {

long idOfItemToDelete = (allItems.get(index).getId());

mDbManager.markItemForDeletion(idOfItemToDelete);

}

}

我认为理想情况下SparseArray系列会有一个getKeys()方法,但它没有。

Tyler Pfaff answered 2019-02-04T11:49:06Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值