diff --git a/common/src/main/java/io/netty/util/collection/IntObjectHashMap.java b/common/src/main/java/io/netty/util/collection/IntObjectHashMap.java index 560489928b..89dfeaecea 100644 --- a/common/src/main/java/io/netty/util/collection/IntObjectHashMap.java +++ b/common/src/main/java/io/netty/util/collection/IntObjectHashMap.java @@ -15,6 +15,7 @@ package io.netty.util.collection; +import java.lang.reflect.Array; import java.util.AbstractCollection; import java.util.Arrays; import java.util.Collection; @@ -51,6 +52,7 @@ public class IntObjectHashMap implements IntObjectMap, Iterable valueCollection; private int size; public IntObjectHashMap() { @@ -78,7 +80,7 @@ public class IntObjectHashMap implements IntObjectMap, Iterable implements IntObjectMap, Iterable implements IntObjectMap, Iterable clazz) { + @SuppressWarnings("unchecked") + V[] outValues = (V[]) Array.newInstance(clazz, size()); + int targetIx = 0; + for (V value : values) { + if (value != null) { + outValues[targetIx++] = value; + } + } + return outValues; + } + @Override public Collection values() { - return new AbstractCollection() { - @Override - public Iterator iterator() { - return new Iterator() { - final Iterator> iter = IntObjectHashMap.this.iterator(); - @Override - public boolean hasNext() { - return iter.hasNext(); - } + Collection valueCollection = this.valueCollection; + if (valueCollection == null) { + this.valueCollection = valueCollection = new AbstractCollection() { + @Override + public Iterator iterator() { + return new Iterator() { + final Iterator> iter = IntObjectHashMap.this.iterator(); + @Override + public boolean hasNext() { + return iter.hasNext(); + } - @Override - public V next() { - return iter.next().value(); - } + @Override + public V next() { + return iter.next().value(); + } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } - @Override - public int size() { - return size; - } - }; + @Override + public int size() { + return size; + } + }; + } + + return valueCollection; } @Override @@ -258,7 +278,7 @@ public class IntObjectHashMap implements IntObjectMap, Iterable implements IntObjectMap, Iterable implements IntObjectMap, Iterable implements IntObjectMap, Iterable implements IntObjectMap, Iterable { /** * Gets the values contained in this map. */ + V[] values(Class clazz); + + /** + * Gets the values contatins in this map as a {@link Collection}. + */ Collection values(); } diff --git a/common/src/test/java/io/netty/util/collection/IntObjectHashMapTest.java b/common/src/test/java/io/netty/util/collection/IntObjectHashMapTest.java index d47df64700..470dc490e5 100644 --- a/common/src/test/java/io/netty/util/collection/IntObjectHashMapTest.java +++ b/common/src/test/java/io/netty/util/collection/IntObjectHashMapTest.java @@ -277,19 +277,28 @@ public class IntObjectHashMapTest { map.put(4, new Value("v4")); map.remove(4); - Collection values = map.values(); - assertEquals(3, values.size()); - + // Ensure values() return all values. Set expected = new HashSet(); + Set actual = new HashSet(); + expected.add(v1); expected.add(v2); expected.add(v3); - Set found = new HashSet(); - for (Value value : values) { - assertTrue(found.add(value)); + Value[] valueArray = map.values(Value.class); + assertEquals(3, valueArray.length); + for (Value value : valueArray) { + assertTrue(actual.add(value)); } - assertEquals(expected, found); + assertEquals(expected, actual); + actual.clear(); + + Collection valueCollection = map.values(); + assertEquals(3, valueCollection.size()); + for (Value value : valueCollection) { + assertTrue(actual.add(value)); + } + assertEquals(expected, actual); } @Test @@ -315,14 +324,14 @@ public class IntObjectHashMapTest { map2.put(key, key); } assertEquals(map1.hashCode(), map2.hashCode()); - assertTrue(map1.equals(map2)); + assertEquals(map1, map2); // Remove one "middle" element, maps should now be non-equals. int[] keys = map1.keys(); map2.remove(keys[50]); assertFalse(map1.equals(map2)); // Put it back; will likely be in a different position, but maps will be equal again. map2.put(keys[50], map1.keys()[50]); - assertTrue(map1.equals(map2)); + assertEquals(map1, map2); assertEquals(map1.hashCode(), map2.hashCode()); // Make map2 have one extra element, will be non-equal. map2.put(1000, 1000); @@ -336,7 +345,7 @@ public class IntObjectHashMapTest { map2.put(key, key); } assertEquals(map1.hashCode(), map2.hashCode()); - assertTrue(map1.equals(map2)); + assertEquals(map1, map2); } @Test