You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/03/27 17:58:18 UTC

svn commit: r389179 - in /incubator/harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/util/HashMap.java test/java/tests/api/java/util/HashMapTest.java

Author: tellison
Date: Mon Mar 27 07:58:16 2006
New Revision: 389179

URL: http://svn.apache.org/viewcvs?rev=389179&view=rev
Log:
Fix for HARMONY-206 (HashMap's behavior is non-compliant with RI when key is reused)

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/HashMap.java
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/HashMapTest.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/HashMap.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/HashMap.java?rev=389179&r1=389178&r2=389179&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/HashMap.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/HashMap.java Mon Mar 27 07:58:16 2006
@@ -41,10 +41,13 @@
 	private static final int DEFAULT_SIZE = 16;
 
 	static class Entry extends MapEntry {
+		final int hash;
+
 		Entry next;
 
 		Entry(Object theKey, Object theValue) {
 			super(theKey, theValue);
+			this.hash = (theKey == null) ? 0 : theKey.hashCode();
 		}
 
 		public Object clone() {
@@ -57,6 +60,10 @@
 		public String toString() {
 			return key + "=" + value;
 		}
+
+		public int hashCode() {
+			return hash;
+		}
 	}
 
 	static class HashMapIterator implements Iterator {
@@ -315,8 +322,8 @@
 	 *            second key to compare
 	 * @return true iff the keys are considered equal
 	 */
-	boolean keysEqual(Object k1, Object k2) {
-		return k1.equals(k2);
+	boolean keysEqual(Object k1, Entry entry) {
+		return entry.hashCode() == k1.hashCode() && k1.equals(entry.key);
 	}
 
 	/**
@@ -391,8 +398,9 @@
 		Entry m;
 		m = elementData[index];
 		if (key != null) {
-			while (m != null && !keysEqual(key, m.key))
+			while(m != null && !keysEqual(key,m)){
 				m = m.next;
+			}
 		} else {
 			while (m != null && m.key != null)
 				m = m.next;
@@ -542,7 +550,7 @@
 		if (key != null) {
 			index = (key.hashCode() & 0x7FFFFFFF) % elementData.length;
 			entry = elementData[index];
-			while (entry != null && !keysEqual(key, entry.key)) {
+			while (entry != null && !keysEqual(key, entry)) {
 				last = entry;
 				entry = entry.next;
 			}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/HashMapTest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/HashMapTest.java?rev=389179&r1=389178&r2=389179&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/HashMapTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/HashMapTest.java Mon Mar 27 07:58:16 2006
@@ -223,6 +223,18 @@
 		assertTrue("Failed with null key", m.get(null).equals("test"));
 		assertTrue("Failed with missing key matching null hash", m
 				.get(new Integer(0)) == null);
+		
+		// Regression for HARMONY-206
+		ReusableKey k = new ReusableKey();
+		HashMap map = new HashMap();
+		k.setKey(1);
+		map.put(k, "value1");
+
+		k.setKey(18);
+		assertNull(map.get(k));
+
+		k.setKey(17);
+		assertNull(map.get(k));
 	}
 
 	/**
@@ -376,6 +388,28 @@
 
 	}
 
+	private static class ReusableKey {
+		private int key = 0;
+
+		public void setKey(int key) {
+			this.key = key;
+		}
+
+		public int hashCode() {
+			return key;
+		}
+
+		public boolean equals(Object o) {
+			if (o == this) {
+				return true;
+			}
+			if (!(o instanceof ReusableKey)) {
+				return false;
+			}
+			return key == ((ReusableKey) o).key;
+		}
+	}
+	
 	/**
 	 * Sets up the fixture, for example, open a network connection. This method
 	 * is called before a test is executed.