어떻게 SparseArray을 반복하는 데?
있는 방법 자바 SparseArray(안드로이드를 위한)을 반복할 있나요?내가 사용sparsearray
쉽게 인덱스로 값을 가져옵니다.나는 하나 찾을 수 없습니다.
나는 해결책을 찾아냈다 그런 것 같은데.나는 제대로 알아채지 못했어.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);
}
Ooor 단지 당신의 자신의 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에 솔직히 현재까지의 가장 쉬운 방법은 반복하는 데를 사용하고 있어.Anko 혹은 안드로이드 KTX에서!(Yazazzello에 안드로이드 KTX지적에 대해 신용)은 코틀린연장 사용합니다.
단순히 전화forEach { i, item -> }
심플 파이다.그냥 당신이 실제로 루프 연주를 하기 전에 배열 크기 길는지 확인합니다.
for(int i = 0, arraySize= mySparseArray.size(); i < arraySize; i++) {
Object obj = mySparseArray.get(/* int key = */ mySparseArray.keyAt(i));
}
이게 도움이 됐으면 좋겠다.
에서 모든 요소를 제거하기 위해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;
}
}
여기 간단한 것이 있습니다.Iterator<T>
그리고.Iterable<T>
의 실장SparseArray<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);
}
}
이 유틸리티 메서드를 작성하면 편리합니다.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을 사용하는 경우 다음과 같은 확장 함수를 사용할 수 있습니다.
fun <T> LongSparseArray<T>.valuesIterator(): Iterator<T> {
val nSize = this.size()
return object : Iterator<T> {
var i = 0
override fun hasNext(): Boolean = i < nSize
override fun next(): T = valueAt(i++)
}
}
fun <T> LongSparseArray<T>.keysIterator(): Iterator<Long> {
val nSize = this.size()
return object : Iterator<Long> {
var i = 0
override fun hasNext(): Boolean = i < nSize
override fun next(): Long = keyAt(i++)
}
}
fun <T> LongSparseArray<T>.entriesIterator(): Iterator<Pair<Long, T>> {
val nSize = this.size()
return object : Iterator<Pair<Long, T>> {
var i = 0
override fun hasNext(): Boolean = i < nSize
override fun next() = Pair(keyAt(i), valueAt(i++))
}
}
필요에 따라서, 리스트로 변환할 수도 있습니다.예제:
sparseArray.keysIterator().asSequence().toList()
아이템을 삭제해도 안전할 것 같습니다.remove
에서LongSparseArray
오름차순으로 되어 있기 때문에 (반복기에 없는) 그 자체입니다.
편집: 수집 수집의(여기 예)를 사용하면 더 쉬운 방법이 있을 것 같습니다.실제로 제가 쓴 것과 매우 유사한 방식으로 구현되어 있습니다.
Gradle에는 다음이 필요합니다.
implementation 'androidx.core:core-ktx:#'
implementation 'androidx.collection:collection-ktx:#'
LongSparseArray의 사용 방법은 다음과 같습니다.
val sparse= LongSparseArray<String>()
for (key in sparse.keyIterator()) {
}
for (value in sparse.valueIterator()) {
}
sparse.forEach { key, value ->
}
Java를 사용하는 사용자에게는LongSparseArrayKt.keyIterator
,LongSparseArrayKt.valueIterator
그리고.LongSparseArrayKt.forEach
,예를들면.다른 사건들도 마찬가지야
대답은 '아니오'입니다 왜냐하면SparseArray
그런 건 없어요~하듯이pst
말하자면, 이건 인터페이스를 제공하지 않습니다.
에서 루프할 수 있습니다.0 - size()
반환되는 값을 건너뜁니다.null
하지만 그게 다예요.
제 코멘트에 기재되어 있듯이, 반복할 필요가 있는 경우는,Map
대신SparseArray
예를 들어,TreeMap
키를 사용하여 순서대로 반복됩니다.
TreeMap<Integer, MyType>
받아들여진 답변에는 구멍이 좀 있다.Sparse Array의 장점은 엔드의 갭을 허용하는 것입니다.이와 같은 두 개의 지도를 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);
}
}
이상적으로는 sparse Array 패밀리는 getKeys() 메서드를 가지고 있지만 실제로는 없습니다.
언급URL : https://stackoverflow.com/questions/7999211/how-to-iterate-through-sparsearray
'programing' 카테고리의 다른 글
롬복에서 세터/게터 1개 누락 (0) | 2022.08.08 |
---|---|
vue 컴포넌트에 다른 입력을 입력할 때 입력 파일 값이 누락되는 이유는 무엇입니까? (0) | 2022.08.08 |
Android에서 모바일 장치의 위도와 경도를 얻는 방법 (0) | 2022.08.08 |
vuex 작업 Vue.js에서 개체 어레이를 정렬할 수 없습니다. (0) | 2022.08.07 |
LD_PRELOAD에서 gdb를 사용하는 방법 (0) | 2022.08.07 |