From 56b6ad3e28f9f86fb3186c96ddd8754e190afdf0 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Fri, 11 Feb 2011 13:32:04 -0800 Subject: Add a new method, LruCache.remove Change-Id: Iae78a2ed4d719d4f14a4677ecb6fe5bc823bb660 http://b/3184897 --- api/current.xml | 15 ++++++++- core/java/android/util/LruCache.java | 28 ++++++++++++++-- .../coretests/src/android/util/LruCacheTest.java | 39 ++++++++++++++++++++++ 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/api/current.xml b/api/current.xml index 1cdf0e93dff6..5f732e1eee20 100644 --- a/api/current.xml +++ b/api/current.xml @@ -206346,6 +206346,19 @@ visibility="public" > + + + + - + diff --git a/core/java/android/util/LruCache.java b/core/java/android/util/LruCache.java index 212205087de4..5578e6ab372c 100644 --- a/core/java/android/util/LruCache.java +++ b/core/java/android/util/LruCache.java @@ -51,6 +51,10 @@ import java.util.Map; * cache.put(key, value); * } * }} + * + *

This class does not allow null to be used as a key or value. A return + * value of null from {@link #get}, {@link #put} or {@link #remove} is + * unambiguous: the key was not in the cache. */ public class LruCache { private final LinkedHashMap map; @@ -86,7 +90,7 @@ public class LruCache { */ public synchronized final V get(K key) { if (key == null) { - throw new NullPointerException(); + throw new NullPointerException("key == null"); } V result = map.get(key); @@ -118,7 +122,7 @@ public class LruCache { */ public synchronized final V put(K key, V value) { if (key == null || value == null) { - throw new NullPointerException(); + throw new NullPointerException("key == null || value == null"); } putCount++; @@ -133,7 +137,7 @@ public class LruCache { private void trimToSize(int maxSize) { while (size > maxSize) { - Map.Entry toEvict = map.eldest(); + Map.Entry toEvict = map.eldest(); // equal to map.entrySet().iterator().next(); if (toEvict == null) { break; // map is empty; if size is not 0 then throw an error below } @@ -154,6 +158,24 @@ public class LruCache { } } + /** + * Removes the entry for {@code key} if it exists. + * + * @return the previous value mapped by {@code key}. Although that entry is + * no longer cached, it has not been passed to {@link #entryEvicted}. + */ + public synchronized final V remove(K key) { + if (key == null) { + throw new NullPointerException("key == null"); + } + + V previous = map.remove(key); + if (previous != null) { + size -= safeSizeOf(key, previous); + } + return previous; + } + /** * Called for entries that have reached the tail of the least recently used * queue and are be removed. The default implementation does nothing. diff --git a/core/tests/coretests/src/android/util/LruCacheTest.java b/core/tests/coretests/src/android/util/LruCacheTest.java index 506315d4872d..cf252e694496 100644 --- a/core/tests/coretests/src/android/util/LruCacheTest.java +++ b/core/tests/coretests/src/android/util/LruCacheTest.java @@ -337,6 +337,45 @@ public final class LruCacheTest extends TestCase { assertSnapshot(cache); } + public void testRemoveDoesNotCallEntryEvicted() { + LruCache cache = new LruCache(10) { + @Override protected void entryEvicted(String key, String value) { + fail(); + } + }; + cache.put("a", "A"); + assertEquals("A", cache.remove("a")); + } + + public void testRemoveWithCustomSizes() { + LruCache cache = new LruCache(10) { + @Override protected int sizeOf(String key, String value) { + return value.length(); + } + }; + cache.put("a", "123456"); + cache.put("b", "1234"); + cache.remove("a"); + assertEquals(4, cache.size()); + } + + public void testRemoveAbsentElement() { + LruCache cache = new LruCache(10); + cache.put("a", "A"); + cache.put("b", "B"); + assertEquals(null, cache.remove("c")); + assertEquals(2, cache.size()); + } + + public void testRemoveNullThrows() { + LruCache cache = new LruCache(10); + try { + cache.remove(null); + fail(); + } catch (NullPointerException expected) { + } + } + private LruCache newCreatingCache() { return new LruCache(3) { @Override protected String create(String key) { -- cgit v1.2.3-59-g8ed1b