You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by py...@apache.org on 2006/08/30 09:27:37 UTC
svn commit: r438409 - in
/incubator/harmony/enhanced/classlib/trunk/modules/luni/src:
main/java/java/util/EnumMap.java
test/java/tests/api/java/util/EnumMapTest.java
Author: pyang
Date: Wed Aug 30 00:27:35 2006
New Revision: 438409
URL: http://svn.apache.org/viewvc?rev=438409&view=rev
Log:
Patch applied for HARMONY-1341 ([classlib][luni] new method entrySet() in java.util.EnumMap)
Modified:
incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/EnumMap.java
incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/EnumMapTest.java
Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/EnumMap.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/EnumMap.java?rev=438409&r1=438408&r2=438409&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/EnumMap.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/EnumMap.java Wed Aug 30 00:27:35 2006
@@ -16,6 +16,7 @@
package java.util;
import java.io.Serializable;
+import java.lang.reflect.Array;
import org.apache.harmony.luni.util.NotYetImplementedException;
@@ -23,27 +24,101 @@
Map<K, V>, Serializable, Cloneable {
private static final long serialVersionUID = 458661240069192865L;
- Class<K> keyType;
+ private Class<K> keyType;
- transient Enum keys[];
+ transient Enum[] keys;
- transient Object values[];
+ transient Object[] values;
- transient boolean hasMapping[];
+ transient boolean[] hasMapping;
- transient int mappingsCount;
+ private transient int mappingsCount;
transient int enumSize;
+ private transient EnumMapEntrySet<K, V> entrySet = null;
+
+ private static class Entry<KT extends Enum<KT>, VT> extends
+ MapEntry<KT, VT> {
+ private final EnumMap<KT, VT> enumMap;
+
+ private final int ordinal;
+
+ Entry(KT theKey, VT theValue, EnumMap<KT, VT> em) {
+ super(theKey, theValue);
+ enumMap = em;
+ ordinal = ((Enum) theKey).ordinal();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (!enumMap.hasMapping[ordinal]) {
+ return false;
+ }
+ boolean isEqual = false;
+ if (object instanceof Map.Entry) {
+ Map.Entry<KT, VT> entry = (Map.Entry<KT, VT>) object;
+ Object enumKey = entry.getKey();
+ if (key.equals(enumKey)) {
+ Object theValue = entry.getValue();
+ isEqual = enumMap.values[ordinal] == null ? null == theValue
+ : enumMap.values[ordinal].equals(theValue);
+ }
+ }
+ return isEqual;
+ }
+
+ @Override
+ public int hashCode() {
+ return (enumMap.keys[ordinal] == null ? 0
+ : enumMap.keys[ordinal].hashCode())
+ ^ (enumMap.values[ordinal] == null ? 0
+ : enumMap.values[ordinal].hashCode());
+ }
+
+ @Override
+ public KT getKey() {
+ checkEntryStatus();
+ return (KT) enumMap.keys[ordinal];
+ }
+
+ @Override
+ public VT getValue() {
+ checkEntryStatus();
+ return (VT) enumMap.values[ordinal];
+ }
+
+ @Override
+ public VT setValue(VT value) {
+ checkEntryStatus();
+ return enumMap.put((KT) enumMap.keys[ordinal], value);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder(enumMap.keys[ordinal]
+ .toString());
+ result.append("="); //$NON-NLS-1$
+ result.append(enumMap.values[ordinal].toString());
+ return result.toString();
+ }
+
+ private void checkEntryStatus() {
+ if (!enumMap.hasMapping[ordinal]) {
+ throw new IllegalStateException();
+ }
+ }
+ }
+
private static class EnumMapIterator<E, KT extends Enum<KT>, VT> implements
Iterator<E> {
- private int position = 0;
+ int position = 0;
- private int prePosition = -1;
+ int prePosition = -1;
- private final EnumMap<KT, VT> enumMap;
+ final EnumMap<KT, VT> enumMap;
- private final MapEntry.Type<E, KT, VT> type;
+ final MapEntry.Type<E, KT, VT> type;
EnumMapIterator(MapEntry.Type<E, KT, VT> value, EnumMap<KT, VT> em) {
enumMap = em;
@@ -89,7 +164,7 @@
enumMap.values[prePosition])).toString();
}
- void checkStatus() {
+ private void checkStatus() {
if (-1 == prePosition) {
throw new IllegalStateException();
}
@@ -197,6 +272,103 @@
}
}
+ private static class EnumMapEntryIterator<E, KT extends Enum<KT>, VT>
+ extends EnumMapIterator<E, KT, VT> {
+ EnumMapEntryIterator(MapEntry.Type<E, KT, VT> value, EnumMap<KT, VT> em) {
+ super(value, em);
+ }
+
+ @Override
+ public E next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ prePosition = position++;
+ return type.get(new Entry<KT, VT>((KT) enumMap.keys[prePosition],
+ (VT) enumMap.values[prePosition], enumMap));
+ }
+ }
+
+ private static class EnumMapEntrySet<KT extends Enum<KT>, VT> extends
+ AbstractSet<Map.Entry<KT, VT>> {
+ private final EnumMap<KT, VT> enumMap;
+
+ EnumMapEntrySet(EnumMap<KT, VT> em) {
+ enumMap = em;
+ }
+
+ @Override
+ public void clear() {
+ enumMap.clear();
+ }
+
+ @Override
+ public boolean contains(Object object) {
+ boolean isEqual = false;
+ if (object instanceof Map.Entry) {
+ Object enumKey = ((Map.Entry) object).getKey();
+ Object enumValue = ((Map.Entry) object).getValue();
+ if (enumMap.containsKey(enumKey)) {
+ VT value = enumMap.get(enumKey);
+ isEqual = (value == null ? null == enumValue : value
+ .equals(enumValue));
+ }
+ }
+ return isEqual;
+ }
+
+ @Override
+ public Iterator<Map.Entry<KT, VT>> iterator() {
+ return new EnumMapEntryIterator<Map.Entry<KT, VT>, KT, VT>(
+ new MapEntry.Type<Map.Entry<KT, VT>, KT, VT>() {
+ public Map.Entry<KT, VT> get(MapEntry<KT, VT> entry) {
+ return entry;
+ }
+ }, enumMap);
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ if (contains(object)) {
+ enumMap.remove(((Map.Entry) object).getKey());
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int size() {
+ return enumMap.size();
+ }
+
+ @Override
+ public Object[] toArray() {
+ Object[] entryArray = new Object[enumMap.size()];
+ return toArray(entryArray);
+ }
+
+ @Override
+ public Object[] toArray(Object[] array) {
+ int size = enumMap.size();
+ int index = 0;
+ Object[] entryArray = array;
+ if (size > array.length) {
+ Class clazz = array.getClass().getComponentType();
+ entryArray = (Object[]) Array.newInstance(clazz, size);
+ }
+ Iterator iter = iterator();
+ for (; index < size; index++) {
+ Map.Entry<KT, VT> entry = (Map.Entry<KT, VT>) iter.next();
+ entryArray[index] = new MapEntry<KT, VT>((KT) entry.getKey(),
+ (VT) entry.getValue());
+ }
+ if (index < array.length) {
+ entryArray[index] = null;
+ }
+ return entryArray;
+ }
+ }
+
/**
* Constructs an empty enum map using the given key type.
*
@@ -324,8 +496,12 @@
*
* @return a set view of the mappings contained in this map.
*/
+ @Override
public Set<Map.Entry<K, V>> entrySet() {
- throw new NotYetImplementedException();
+ if (null == entrySet) {
+ entrySet = new EnumMapEntrySet<K, V>(this);
+ }
+ return entrySet;
}
/**
Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/EnumMapTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/EnumMapTest.java?rev=438409&r1=438408&r2=438409&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/EnumMapTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/EnumMapTest.java Wed Aug 30 00:27:35 2006
@@ -24,8 +24,6 @@
import java.util.NoSuchElementException;
import java.util.Set;
-import org.apache.harmony.luni.util.NotYetImplementedException;
-
import junit.framework.TestCase;
public class EnumMapTest extends TestCase {
@@ -40,7 +38,38 @@
enum Empty {
//Empty
}
-
+
+ private static class MockEntry<K, V> implements Map.Entry<K, V> {
+ private K key;
+
+ private V value;
+
+ public MockEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ return (key == null ? 0 : key.hashCode())
+ ^ (value == null ? 0 : value.hashCode());
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ public V setValue(V object) {
+ V oldValue = value;
+ value = object;
+ return oldValue;
+ }
+ }
+
/**
* @tests java.util.EnumMap#EnumMap(Class)
@@ -265,6 +294,236 @@
}
/**
+ * @tests java.util.EnumMap#entrySet()
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_entrySet() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ MockEntry mockEntry = new MockEntry(Size.Middle, 1);
+ Set set = enumSizeMap.entrySet();
+
+ Set set1 = enumSizeMap.entrySet();
+ assertSame("Should be same", set1, set); //$NON-NLS-1$
+ try {
+ set.add(mockEntry);
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+
+ assertTrue("Returned false for contained object", set//$NON-NLS-1$
+ .contains(mockEntry));
+ mockEntry = new MockEntry(Size.Middle, null);
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .contains(mockEntry));
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .contains(Size.Small));
+ mockEntry = new MockEntry(new Integer(1), 1);
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .contains(mockEntry));
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .contains(new Integer(1)));
+
+ mockEntry = new MockEntry(Size.Big, null);
+ assertTrue("Returned false for contained object", set//$NON-NLS-1$
+ .contains(mockEntry));
+ assertTrue("Returned false when the object can be removed", set //$NON-NLS-1$
+ .remove(mockEntry));
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .contains(mockEntry));
+ assertFalse("Returned true when the object can not be removed", set //$NON-NLS-1$
+ .remove(mockEntry));
+ mockEntry = new MockEntry(new Integer(1), 1);
+ assertFalse("Returned true when the object can not be removed", set //$NON-NLS-1$
+ .remove(mockEntry));
+ assertFalse("Returned true when the object can not be removed", set //$NON-NLS-1$
+ .remove(new Integer(1)));
+
+ // The set is backed by the map so changes to one are reflected by the
+ // other.
+ enumSizeMap.put(Size.Big, 3);
+ mockEntry = new MockEntry(Size.Big, 3);
+ assertTrue("Returned false for contained object", set//$NON-NLS-1$
+ .contains(mockEntry));
+ enumSizeMap.remove(Size.Big);
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .contains(mockEntry));
+
+ assertEquals("Wrong size", 1, set.size()); //$NON-NLS-1$
+ set.clear();
+ assertEquals("Wrong size", 0, set.size()); //$NON-NLS-1$
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ Collection c = new ArrayList();
+ c.add(new MockEntry(Size.Middle, 1));
+ assertTrue("Return wrong value", set.containsAll(c)); //$NON-NLS-1$
+ assertTrue("Remove does not success", set.removeAll(c)); //$NON-NLS-1$
+
+ enumSizeMap.put(Size.Middle, 1);
+ c.add(new MockEntry(Size.Big, 3));
+ assertTrue("Remove does not success", set.removeAll(c)); //$NON-NLS-1$
+ assertFalse("Should return false", set.removeAll(c)); //$NON-NLS-1$
+ assertEquals("Wrong size", 1, set.size()); //$NON-NLS-1$
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ c = new ArrayList();
+ c.add(new MockEntry(Size.Middle, 1));
+ c.add(new MockEntry(Size.Big, 3));
+
+ assertTrue("Retain does not success", set.retainAll(c)); //$NON-NLS-1$
+ assertEquals("Wrong size", 1, set.size()); //$NON-NLS-1$
+ assertFalse("Should return false", set.retainAll(c)); //$NON-NLS-1$
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+
+ set = enumSizeMap.entrySet();
+ Object[] array = set.toArray();
+ assertEquals("Wrong length", 2, array.length); //$NON-NLS-1$
+ Map.Entry entry = (Map.Entry) array[0];
+ assertEquals("Wrong key", Size.Middle, entry.getKey()); //$NON-NLS-1$
+ assertEquals("Wrong value", 1, entry.getValue()); //$NON-NLS-1$
+
+ Object[] array1 = new Object[10];
+ array1 = set.toArray();
+ assertEquals("Wrong length", 2, array1.length); //$NON-NLS-1$
+ entry = (Map.Entry) array[0];
+ assertEquals("Wrong key", Size.Middle, entry.getKey()); //$NON-NLS-1$
+ assertEquals("Wrong value", 1, entry.getValue()); //$NON-NLS-1$
+
+ array1 = new Object[10];
+ array1 = set.toArray(array1);
+ assertEquals("Wrong length", 10, array1.length); //$NON-NLS-1$
+ entry = (Map.Entry) array[1];
+ assertEquals("Wrong key", Size.Big, entry.getKey()); //$NON-NLS-1$
+ assertNull("Should be null", array1[2]); //$NON-NLS-1$
+
+ set = enumSizeMap.entrySet();
+ Integer integer = new Integer("1"); //$NON-NLS-1$
+ assertFalse("Returned true when the object can not be removed", set //$NON-NLS-1$
+ .remove(integer));
+ assertTrue("Returned false when the object can be removed", set //$NON-NLS-1$
+ .remove(entry));
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ Iterator iter = set.iterator();
+ entry = (Map.Entry) iter.next();
+ assertTrue("Returned false for contained object", set.contains(entry)); //$NON-NLS-1$
+ mockEntry = new MockEntry(Size.Middle, 2);
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .contains(mockEntry));
+ mockEntry = new MockEntry(new Integer(2), 2);
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .contains(mockEntry));
+ entry = (Map.Entry) iter.next();
+ assertTrue("Returned false for contained object", set.contains(entry)); //$NON-NLS-1$
+
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.remove(Size.Big);
+ mockEntry = new MockEntry(Size.Big, null);
+ assertEquals("Wrong size", 1, set.size()); //$NON-NLS-1$
+ assertFalse("Returned true for uncontained object", set.contains(mockEntry)); //$NON-NLS-1$
+ enumSizeMap.put(Size.Big, 2);
+ mockEntry = new MockEntry(Size.Big, 2);
+ assertTrue("Returned false for contained object", set //$NON-NLS-1$
+ .contains(mockEntry));
+
+ iter.remove();
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException"); //$NON-NLS-1$
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ try {
+ entry.setValue(2);
+ fail("Should throw IllegalStateException"); //$NON-NLS-1$
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ try {
+ set.contains(entry);
+ fail("Should throw IllegalStateException"); //$NON-NLS-1$
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ iter = set.iterator();
+ entry = (Map.Entry) iter.next();
+ assertEquals("Wrong key", Size.Middle, entry.getKey()); //$NON-NLS-1$
+
+ assertTrue("Returned false for contained object", set.contains(entry)); //$NON-NLS-1$
+ enumSizeMap.put(Size.Middle, 3);
+ assertTrue("Returned false for contained object", set.contains(entry)); //$NON-NLS-1$
+ entry.setValue(2);
+ assertTrue("Returned false for contained object", set.contains(entry)); //$NON-NLS-1$
+ assertFalse("Returned true for uncontained object", set //$NON-NLS-1$
+ .remove(new Integer(1)));
+
+ iter.next();
+ //The following test case fails on RI.
+ assertEquals("Wrong key", Size.Middle, entry.getKey()); //$NON-NLS-1$
+ set.clear();
+ assertEquals("Wrong size", 0, set.size()); //$NON-NLS-1$
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ iter = set.iterator();
+ mockEntry = new MockEntry(Size.Middle, 1);
+
+ assertFalse("Wrong result", entry.equals(mockEntry)); //$NON-NLS-1$
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException"); //$NON-NLS-1$
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ entry = (Map.Entry) iter.next();
+ assertEquals("Wrong key", Size.Middle, entry.getKey()); //$NON-NLS-1$
+ assertTrue("Should return true", entry.equals(mockEntry)); //$NON-NLS-1$
+ assertEquals("Should be equal", mockEntry.hashCode(), entry.hashCode()); //$NON-NLS-1$
+ mockEntry = new MockEntry(Size.Big, 1);
+ assertFalse("Wrong result", entry.equals(mockEntry)); //$NON-NLS-1$
+
+ entry = (Map.Entry) iter.next();
+ assertFalse("Wrong result", entry.equals(mockEntry)); //$NON-NLS-1$
+ assertEquals("Wrong key", Size.Big, entry.getKey()); //$NON-NLS-1$
+ iter.remove();
+ assertFalse("Wrong result", entry.equals(mockEntry)); //$NON-NLS-1$
+ assertEquals("Wrong size", 1, set.size()); //$NON-NLS-1$
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException"); //$NON-NLS-1$
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ try {
+ iter.next();
+ fail("Should throw NoSuchElementException"); //$NON-NLS-1$
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ /**
* @tests java.util.EnumMap#keySet()
*/
@SuppressWarnings( { "unchecked", "boxing" })
@@ -509,7 +768,7 @@
assertEquals("Return wrong value", 2, enumColorMap.put(Color.Blue, //$NON-NLS-1$
new Double(4)));
}
-
+
/**
* @tests java.util.EnumMap#putAll(Map)
*/
@@ -518,31 +777,26 @@
EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
enumColorMap.put(Color.Green, 2);
- // TODO: The EnumMap.entrySet() will be implemented later.
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ enumColorMap.putAll(enumSizeMap);
+
+ enumSizeMap.put(Size.Big, 1);
try {
- EnumMap enumSizeMap = new EnumMap(Size.class);
enumColorMap.putAll(enumSizeMap);
-
- enumSizeMap.put(Size.Big, 1);
- try {
- enumColorMap.putAll(enumSizeMap);
- fail("Expected ClassCastException"); //$NON-NLS-1$
- } catch (ClassCastException e) {
- // Expected
- }
-
- EnumMap enumColorMap1 = new EnumMap<Color, Double>(Color.class);
- enumColorMap1.put(Color.Blue, 3);
- enumColorMap.putAll(enumColorMap1);
- assertEquals("Get returned incorrect value for given key", 3, //$NON-NLS-1$
- enumColorMap.get(Color.Blue));
- assertEquals("Wrong Size", 2, enumColorMap.size()); //$NON-NLS-1$
-
- enumColorMap = new EnumMap<Color, Double>(Color.class);
- } catch (NotYetImplementedException e) {
+ fail("Expected ClassCastException"); //$NON-NLS-1$
+ } catch (ClassCastException e) {
// Expected
}
-
+
+ EnumMap enumColorMap1 = new EnumMap<Color, Double>(Color.class);
+ enumColorMap1.put(Color.Blue, 3);
+ enumColorMap.putAll(enumColorMap1);
+ assertEquals("Get returned incorrect value for given key", 3, //$NON-NLS-1$
+ enumColorMap.get(Color.Blue));
+ assertEquals("Wrong Size", 2, enumColorMap.size()); //$NON-NLS-1$
+
+ enumColorMap = new EnumMap<Color, Double>(Color.class);
+
HashMap hashColorMap = null;
try {
enumColorMap.putAll(hashColorMap);
@@ -562,7 +816,7 @@
.get(Color.Red));
hashColorMap.put(Color.Red, new Integer(1));
enumColorMap.putAll(hashColorMap);
- assertEquals("Get returned incorrect value for given key", new Integer( //$NON-NLS-1$
+ assertEquals("Get returned incorrect value for given key", new Integer(//$NON-NLS-1$
2), enumColorMap.get(Color.Green));
hashColorMap.put(Size.Big, 3);
try {
@@ -581,7 +835,7 @@
// Expected
}
}
-
+
/**
* @tests java.util.EnumMap#remove(Object)
*/