Подтвердить что ты не робот

SparseArray, проверьте, существует ли ключ

Я реализовал кеш Bitmap с помощью HashMap<Integer, Bitmap> и получил следующее предупреждение в Eclipse:

Вместо этого используйте новую SparseArray (...) для лучшей производительности.

Я никогда не слышал об этом классе раньше, но, проверяя его, у него нет метода containsKey(), который я вызывал при извлечении Bitmap из кеша, чтобы проверить, существует ли он в кеше, и если это не так, добавьте его.

Любые идеи о том, как лучше всего проверить, существует ли ключ?

Я думаю, я мог бы изменить код, чтобы использовать эту перегрузку и проверить на нуль?

Bitmap bitmap = cache.get(key, null); 
4b9b3361

Ответ 1

Вы можете использовать:

Bitmap bitmap = cache.get(key, null); 

Но поймите, что это то же самое, что get(key):

Bitmap bitmap = cache.get(key); 

Лучший способ использовать get(key, default) - предоставить общий случай по умолчанию, что-то является допустимой заменой, когда ключ не найден.

Но нет веской причины не использовать if(get(key) != null) в качестве быстрой замены для contains().

Ответ 2

Следовательно, ваше значение может быть нулевым в разных ситуациях, я бы предложил использовать indexOfKey(int key) Вот ссылка indexOfKey (int key).

Затем просто проверьте отрицательное возвращаемое значение

if(mySparseArray.indexOfKey(int) < 0) {
   //Item does not exist. Do something relevant 
}

Ответ 3

Цитата из документации.

Целые числа карт SparseArrays для объектов. В отличие от обычного массива объектов, в индексах могут быть пробелы. Он должен быть более эффективным, чем использование HashMap для сопоставления целых чисел с объектами.

Вы можете использовать get (int), который также возвращает значение null, если ключ не найден. Как;

Bitmap bitmap = cache.get(ключ);

Ответ 4

Выполняя реализацию SparseArray, кажется интуитивно понятным, что он может иметь лучшую производительность (временную сложность), чем HashMap (кроме более низкого требования к пространству, что имеет смысл для мобильной среды), поскольку член get() SparseArray использует двоичный поиск (O (log N)), тогда как для HashMap используется индексирование массивов (O (1)).

Предоставление реализации метода get() для обоих классов (as-is):

public V get(Object key) { // for HashMap
    if (key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
            e != null;
            e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
            return e.value;
    }
    return null;
}

public E get(int key, E valueIfKeyNotFound) {  //for SparseArray
    int i = binarySearch(mKeys, 0, mSize, key);

    if (i < 0 || mValues[i] == DELETED) {
        return valueIfKeyNotFound;
    } else {
        return (E) mValues[i];
    }
}

относительно того, следует ли использовать indexOfKey (key) < 0 или get (key) == null для проверки существования ключа в SparseArray, все нормально, поскольку оба используют двоичный поиск под ним.

public int indexOfKey(int key) {  // for SparseArray
    if (mGarbage) {
        gc();
    }

    return binarySearch(mKeys, 0, mSize, key);
}

Ответ 5

Несколько способов:

  1. Если вы все равно хотите использовать значение, связанное с ключом, вы можете использовать get():

    val sparseArray = SparseArray<String>()
    val someKey = 123
    val someValue: String? = sparseArray[someKey]
    if(someValue!=null){
        //do something
    }
    

Обратите внимание, что в отличие от того, что думает IDE, он может быть нулевым, поэтому я добавил его ? ,

  1. если вы просто хотите проверить, существует ли он, вы можете использовать indexOfKey(key) >= 0

  2. Если вам не нравится вышеупомянутое, и вы хотите более читабельную опцию, вы можете использовать containsKey зависимости ktx-collection:

    implementation 'androidx.core:core-ktx:#'
    implementation 'androidx.collection:collection-ktx:#'
    

Использование:

    val sparseArray = SparseArray<String>()
    val someKey = 123
    if (sparseArray.containsKey(someKey)) {
        //do something
    }