From e5c2fafe26c97faabb79966191272f5c5c832db4 Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Fri, 28 Sep 2018 22:38:02 -0400 Subject: Add replace to map-like collections This was added to Map in API 24 which users of ArrayMap are able to use, but there's no reason ArrayMap, SimpleArrayMap, or the primitive-specialized collection users shouldn't have access on all API levels. Bug: 116778381 Test: ./gradlew :collection:build Change-Id: I304cce70a50786f52b843ecd0ca14d1008b7a004 --- collection/api/current.txt | 3 +++ .../java/androidx/collection/LongSparseArray.java | 17 ++++++++++++++++ .../java/androidx/collection/SimpleArrayMap.java | 15 ++++++++++++++ .../androidx/collection/SparseArrayCompat.java | 17 ++++++++++++++++ .../androidx/collection/LongSparseArrayTest.java | 23 ++++++++++++++++++++++ .../androidx/collection/SimpleArrayMapTest.java | 23 ++++++++++++++++++++++ .../androidx/collection/SparseArrayCompatTest.java | 23 ++++++++++++++++++++++ 7 files changed, 121 insertions(+) (limited to 'collection') diff --git a/collection/api/current.txt b/collection/api/current.txt index 70490b8a4f2..5d2f7c4065e 100644 --- a/collection/api/current.txt +++ b/collection/api/current.txt @@ -93,6 +93,7 @@ package androidx.collection { method public E putIfAbsent(long, E); method public void remove(long); method public void removeAt(int); + method public E replace(long, E); method public void setValueAt(int, E); method public int size(); method public E valueAt(int); @@ -138,6 +139,7 @@ package androidx.collection { method public V putIfAbsent(K, V); method public V remove(java.lang.Object); method public V removeAt(int); + method public V replace(K, V); method public V setValueAt(int, V); method public int size(); method public V valueAt(int); @@ -164,6 +166,7 @@ package androidx.collection { method public void remove(int); method public void removeAt(int); method public void removeAtRange(int, int); + method public E replace(int, E); method public void setValueAt(int, E); method public int size(); method public E valueAt(int); diff --git a/collection/src/main/java/androidx/collection/LongSparseArray.java b/collection/src/main/java/androidx/collection/LongSparseArray.java index 451b7f78eda..41400ed6bbc 100644 --- a/collection/src/main/java/androidx/collection/LongSparseArray.java +++ b/collection/src/main/java/androidx/collection/LongSparseArray.java @@ -152,6 +152,23 @@ public class LongSparseArray implements Cloneable { } } + /** + * Replace the mapping for {@code key} only if it is already mapped to a value. + * @param key The key of the mapping to replace. + * @param value The value to store for the given key. + * @return Returns the previous mapped value or null. + */ + @Nullable + public E replace(long key, E value) { + int index = indexOfKey(key); + if (index >= 0) { + E oldValue = (E) mValues[index]; + mValues[index] = value; + return oldValue; + } + return null; + } + private void gc() { // Log.e("SparseArray", "gc start with " + mSize); diff --git a/collection/src/main/java/androidx/collection/SimpleArrayMap.java b/collection/src/main/java/androidx/collection/SimpleArrayMap.java index 73e765a2e7c..816e6346656 100644 --- a/collection/src/main/java/androidx/collection/SimpleArrayMap.java +++ b/collection/src/main/java/androidx/collection/SimpleArrayMap.java @@ -608,6 +608,21 @@ public class SimpleArrayMap { return (V)old; } + /** + * Replace the mapping for {@code key} only if it is already mapped to a value. + * @param key The key of the mapping to replace. + * @param value The value to store for the given key. + * @return Returns the previous mapped value or null. + */ + @Nullable + public V replace(K key, V value) { + int index = indexOfKey(key); + if (index >= 0) { + return setValueAt(index, value); + } + return null; + } + /** * Return the number of items in this array map. */ diff --git a/collection/src/main/java/androidx/collection/SparseArrayCompat.java b/collection/src/main/java/androidx/collection/SparseArrayCompat.java index d17eca4cd04..b956bb0e58c 100644 --- a/collection/src/main/java/androidx/collection/SparseArrayCompat.java +++ b/collection/src/main/java/androidx/collection/SparseArrayCompat.java @@ -169,6 +169,23 @@ public class SparseArrayCompat implements Cloneable { } } + /** + * Replace the mapping for {@code key} only if it is already mapped to a value. + * @param key The key of the mapping to replace. + * @param value The value to store for the given key. + * @return Returns the previous mapped value or null. + */ + @Nullable + public E replace(int key, E value) { + int index = indexOfKey(key); + if (index >= 0) { + E oldValue = (E) mValues[index]; + mValues[index] = value; + return oldValue; + } + return null; + } + private void gc() { // Log.e("SparseArray", "gc start with " + mSize); diff --git a/collection/src/test/java/androidx/collection/LongSparseArrayTest.java b/collection/src/test/java/androidx/collection/LongSparseArrayTest.java index c8098bc90a1..33fc679f741 100644 --- a/collection/src/test/java/androidx/collection/LongSparseArrayTest.java +++ b/collection/src/test/java/androidx/collection/LongSparseArrayTest.java @@ -82,6 +82,29 @@ public class LongSparseArrayTest { assertNull(map.putIfAbsent(1L, "2")); } + @Test + public void replaceWhenAbsentDoesNotStore() { + LongSparseArray map = new LongSparseArray<>(); + assertNull(map.replace(1L, "1")); + assertFalse(map.containsKey(1L)); + } + + @Test + public void replaceStoresAndReturnsOldValue() { + LongSparseArray map = new LongSparseArray<>(); + map.put(1L, "1"); + assertEquals("1", map.replace(1L, "2")); + assertEquals("2", map.get(1L)); + } + + @Test + public void replaceStoresAndReturnsNullWhenMappedToNull() { + LongSparseArray map = new LongSparseArray<>(); + map.put(1L, null); + assertNull(map.replace(1L, "1")); + assertEquals("1", map.get(1L)); + } + @Test public void isEmpty() { LongSparseArray LongSparseArray = new LongSparseArray<>(); diff --git a/collection/src/test/java/androidx/collection/SimpleArrayMapTest.java b/collection/src/test/java/androidx/collection/SimpleArrayMapTest.java index 7326832deeb..6bb86da7eea 100644 --- a/collection/src/test/java/androidx/collection/SimpleArrayMapTest.java +++ b/collection/src/test/java/androidx/collection/SimpleArrayMapTest.java @@ -86,6 +86,29 @@ public class SimpleArrayMapTest { assertNull(map.putIfAbsent("one", "2")); } + @Test + public void replaceWhenAbsentDoesNotStore() { + SimpleArrayMap map = new SimpleArrayMap<>(); + assertNull(map.replace("one", "1")); + assertFalse(map.containsKey("one")); + } + + @Test + public void replaceStoresAndReturnsOldValue() { + SimpleArrayMap map = new SimpleArrayMap<>(); + map.put("one", "1"); + assertEquals("1", map.replace("one", "2")); + assertEquals("2", map.get("one")); + } + + @Test + public void replaceStoresAndReturnsNullWhenMappedToNull() { + SimpleArrayMap map = new SimpleArrayMap<>(); + map.put("one", null); + assertNull(map.replace("one", "1")); + assertEquals("1", map.get("one")); + } + /** * Attempt to generate a ConcurrentModificationException in ArrayMap. */ diff --git a/collection/src/test/java/androidx/collection/SparseArrayCompatTest.java b/collection/src/test/java/androidx/collection/SparseArrayCompatTest.java index 6d4ab3a6f6d..556694fe401 100644 --- a/collection/src/test/java/androidx/collection/SparseArrayCompatTest.java +++ b/collection/src/test/java/androidx/collection/SparseArrayCompatTest.java @@ -82,6 +82,29 @@ public class SparseArrayCompatTest { assertNull(map.putIfAbsent(1, "2")); } + @Test + public void replaceWhenAbsentDoesNotStore() { + SparseArrayCompat map = new SparseArrayCompat<>(); + assertNull(map.replace(1, "1")); + assertFalse(map.containsKey(1)); + } + + @Test + public void replaceStoresAndReturnsOldValue() { + SparseArrayCompat map = new SparseArrayCompat<>(); + map.put(1, "1"); + assertEquals("1", map.replace(1, "2")); + assertEquals("2", map.get(1)); + } + + @Test + public void replaceStoresAndReturnsNullWhenMappedToNull() { + SparseArrayCompat map = new SparseArrayCompat<>(); + map.put(1, null); + assertNull(map.replace(1, "1")); + assertEquals("1", map.get(1)); + } + @Test public void isEmpty() throws Exception { SparseArrayCompat sparseArrayCompat = new SparseArrayCompat<>(); -- cgit v1.2.3