diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 72de0da81..26ca62fcb 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -22,6 +22,10 @@ + + Added method "LRUMap#get(Object, boolean)" that allows to query the map + without affecting the least recently used order. + Changed return type of "ListOrderedSet#remove(int)" from Object to the generic type parameter. diff --git a/src/main/java/org/apache/commons/collections4/map/LRUMap.java b/src/main/java/org/apache/commons/collections4/map/LRUMap.java index 38b9de76f..80e92fc54 100644 --- a/src/main/java/org/apache/commons/collections4/map/LRUMap.java +++ b/src/main/java/org/apache/commons/collections4/map/LRUMap.java @@ -116,7 +116,7 @@ public class LRUMap * Constructs a new, empty map with the specified initial capacity and * load factor. * - * @param maxSize the maximum size of the ma + * @param maxSize the maximum size of the map * @param loadFactor the load factor * @param scanUntilRemovable scan until a removeable entry is found, default false * @throws IllegalArgumentException if the maximum size is less than one @@ -166,18 +166,36 @@ public class LRUMap * Gets the value mapped to the key specified. *

* This operation changes the position of the key in the map to the - * most recently used position (first). + * most recently used position (last). * * @param key the key * @return the mapped value, null if no match */ @Override public V get(final Object key) { + return get(key, true); + } + + /** + * Gets the value mapped to the key specified. + *

+ * If {@code updateToMRU} is {@code true}, the position of the key in the map + * is changed to the most recently used position (last), otherwise the iteration + * order is not changed by this operation. + * + * @param key the key + * @param updateToMRU whether the key shall be updated to the + * most recently used position + * @return the mapped value, null if no match + */ + public V get(final Object key, final boolean updateToMRU) { final LinkEntry entry = getEntry(key); if (entry == null) { return null; } - moveToMRU(entry); + if (updateToMRU) { + moveToMRU(entry); + } return entry.getValue(); } @@ -214,7 +232,7 @@ public class LRUMap /** * Updates an existing key-value mapping. *

- * This implementation moves the updated entry to the top of the list + * This implementation moves the updated entry to the end of the list * using {@link #moveToMRU(AbstractLinkedMap.LinkEntry)}. * * @param entry the entry to update diff --git a/src/test/java/org/apache/commons/collections4/map/LRUMapTest.java b/src/test/java/org/apache/commons/collections4/map/LRUMapTest.java index 9c0d7d6c6..f47741e3d 100644 --- a/src/test/java/org/apache/commons/collections4/map/LRUMapTest.java +++ b/src/test/java/org/apache/commons/collections4/map/LRUMapTest.java @@ -224,6 +224,55 @@ public class LRUMapTest extends AbstractOrderedMapTest { assertSame(values[3], vit.next()); } + public void testAccessOrder2() { + if (!isPutAddSupported() || !isPutChangeSupported()) { + return; + } + final K[] keys = getSampleKeys(); + final V[] values = getSampleValues(); + Iterator kit = null; + Iterator vit = null; + + resetEmpty(); + LRUMap lruMap = (LRUMap) map; + + lruMap.put(keys[0], values[0]); + lruMap.put(keys[1], values[1]); + kit = lruMap.keySet().iterator(); + assertSame(keys[0], kit.next()); + assertSame(keys[1], kit.next()); + vit = lruMap.values().iterator(); + assertSame(values[0], vit.next()); + assertSame(values[1], vit.next()); + + // no change to order + lruMap.put(keys[1], values[1]); + kit = lruMap.keySet().iterator(); + assertSame(keys[0], kit.next()); + assertSame(keys[1], kit.next()); + vit = lruMap.values().iterator(); + assertSame(values[0], vit.next()); + assertSame(values[1], vit.next()); + + // no change to order + lruMap.get(keys[1], false); + kit = lruMap.keySet().iterator(); + assertSame(keys[0], kit.next()); + assertSame(keys[1], kit.next()); + vit = lruMap.values().iterator(); + assertSame(values[0], vit.next()); + assertSame(values[1], vit.next()); + + // change to order + lruMap.get(keys[0], true); + kit = lruMap.keySet().iterator(); + assertSame(keys[1], kit.next()); + assertSame(keys[0], kit.next()); + vit = lruMap.values().iterator(); + assertSame(values[1], vit.next()); + assertSame(values[0], vit.next()); + } + @SuppressWarnings("unchecked") public void testClone() { final LRUMap map = new LRUMap(10);