>From my earlier posts:
1. >> Although one (including my good self!) might initially think that
a key-value class and a Map.Entry class are interchangeable, this is
not
in fact the case. DefaultMapEntry is not suitable for use as a general
purpose KeyValue class, as it is effectively non-extendable... [due to
#equals and #hashCode being defined by Map.Entry API doc]
2. >> My suggested solution is to add a class [KeyValuePair.java]
containing the code from DefaultMapEntry, but not implementing
Map.Entry. DefaultMapEntry can then subclass [KeyValuePair] and
implement Map.Entry
I actually missed the big reason why KeyValuePair and Map.Entry are not
interchangeable. A Map.Entry's key is an invariant, while a
KeyValuePair's key is mutable. The key-invariant property means that
the existing DefaultMapEntry implementation is in fact broken - the
#setKey method should not be present. Note that the Map.Entry impls in
java.util do not feature a key mutator (and of course - far more
importantly - the Map.Entry interface itself does not).
It follows that my suggested solution from (1) above is bogus, as
KeyValuePair has a #setKey method which DefaultMapEntry would inherit.
To retain the key-invariant property, DefaultMapEntry would have to
override #setKey to either (a) silently do nothing, or (b) throw an
UnsupportedOperationException or such; - both horrible options.
Moreover, since the suggested hierarchial relationship between the two
classes was based on a faulty understanding of their similarity, it's
best to ditch that relationship and have the two classes stand alone.
I've attached implementations/patches to that effect. However, all is
not entirely lost ;) as KeyValuePair has a constructor that takes a
Map.Entry and also has a #toMapEntry method, thus retaining a bridge
between the two classes.
> I'm happy to add it....with a test case :-)
> Stephen
Test class for KeyValuePair attached. Also included is a test class for
DefaultMapEntry (TestMapEntry.java) as it does not appear to have one
(or am I somehow missing it?); also a patch for TestAll to include the
new test classes.
- Neil
/*
* $Header:
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/collections/DefaultMapEntry.java,v
1.11 2003/08/31 17:26:43 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.collections;
import java.util.Map;
/**
* A mutable key-value pair. Note that a <code>KeyValuePair</code> instance
* may not contain itself as a key or value.
*
* @since Commons Collections 3.0
* @version $Revision: $
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Michael A. Smith</a>
* @author Neil O'Toole
*/
public class KeyValuePair
{
/** The key */
private Object key;
/** The value */
private Object value;
/**
* Constructs a new <Code>KeyValuePair</Code> with a null key
* and null value.
*/
public KeyValuePair()
{
}
/**
* Constructs a new <Code>KeyValuePair</Code> with the given
* key and given value.
*
* @param key the key for the entry, may be null
* @param value the value for the entry, may be null
*/
public KeyValuePair(Object key, Object value)
{
this.key = key;
this.value = value;
}
/**
* Copy constructor.
*/
public KeyValuePair(KeyValuePair copy)
{
this.key = copy.getKey();
this.value = copy.getValue();
}
/**
* Constructs a new <Code>KeyValuePair</Code> with key
* and value from the supplied <code>Map.Entry</code>.
*/
public KeyValuePair(Map.Entry entry)
{
this.key = entry.getKey();
this.value = entry.getValue();
}
/**
* Returns true if the compared object is also a <code>KeyValuePair</code>,
* and its key and value are equal to this object's key and value.
*/
public boolean equals(Object o)
{
if (o == this)
{
return true;
}
if (o instanceof KeyValuePair == false)
{
return false;
}
KeyValuePair kv2 = (KeyValuePair) o;
return (
(getKey() == null ? kv2.getKey() == null :
getKey().equals(kv2.getKey()))
&& (getValue() == null ? kv2.getValue() == null :
getValue().equals(kv2.getValue())));
}
/**
* Generates hashcode as per [EMAIL PROTECTED] Map.Entry#hashCode}, but note
that
* subclasses may override this method to provide a more appropriate hash.
*
* @return a hash generated as per the Map.Entry#hashCode javadoc.
*/
public int hashCode()
{
return ((getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() ==
null ? 0 : getValue().hashCode()));
}
/**
* Returns the key.
*
* @return the key
*/
public Object getKey()
{
return key;
}
/**
* Returns the value.
*
* @return the value
*/
public Object getValue()
{
return value;
}
/**
* Sets the key.
*
* @param key the new key
* @return the old key
* @throws IllegalArgumentException if key is this object
*/
public Object setKey(Object key)
{
if (key == this)
{
throw new IllegalArgumentException("A KeyValuePair may not
contain itself as a key.");
}
final Object old = this.key;
this.key = key;
return old;
}
/**
* Sets the value.
*
* @return the old value of the value
* @param value the new value
* @throws IllegalArgumentException if value is this object
*/
public Object setValue(Object value)
{
if (value == this)
{
throw new IllegalArgumentException("A KeyValuePair may not
contain itself as a value.");
}
final Object old = this.value;
this.value = value;
return old;
}
/**
* Returns a new <code>Map.Entry</code> object with key and value from this
<code>KeyValuePair</code>.
*/
public Map.Entry toMapEntry()
{
return new DefaultMapEntry(this.getKey(), this.getValue());
}
public String toString()
{
return new
StringBuffer().append(getKey()).append('=').append(getValue()).toString();
}
}
Index: DefaultMapEntry.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/collections/DefaultMapEntry.java,v
retrieving revision 1.11
diff -u -r1.11 DefaultMapEntry.java
--- DefaultMapEntry.java 31 Aug 2003 17:26:43 -0000 1.11
+++ DefaultMapEntry.java 25 Sep 2003 05:14:06 -0000
@@ -60,18 +60,26 @@
import java.util.Map;
/**
- * A default implementation of [EMAIL PROTECTED] java.util.Map.Entry}
+ * A default implementation of [EMAIL PROTECTED] java.util.Map.Entry}. A
+ * <code>Map.Entry</code>'s key cannot be changed, and thus
+ * the key-related fields and methods are final.
+ *
+ * Additionally, note that the <code>#equals</code>
+ * and <code>#hashCode</code> methods are implemented as specified by
+ * the <code>Map.Entry</code> API doc, and
+ * thus these methods are also declared final.
*
* @since Commons Collections 1.0
* @version $Revision: 1.11 $ $Date: 2003/08/31 17:26:43 $
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Michael A. Smith</a>
+ * @author Neil O'Toole
*/
public class DefaultMapEntry implements Map.Entry {
/** The key */
- private Object key;
+ private final Object key;
/** The value */
private Object value;
@@ -80,6 +88,7 @@
* and null value.
*/
public DefaultMapEntry() {
+ this.key = null;
}
/**
@@ -93,13 +102,23 @@
this.key = key;
this.value = value;
}
+
+
+ /**
+ * Copy constructor - creates a new <Code>DefaultMapEntry</Code> with
+ * key and value from the supplied Map.Entry.
+ *
+ */
+ public DefaultMapEntry(Map.Entry copy) {
+ this.key = copy.getKey();
+ this.value = copy.getValue();
+ }
/**
* Implemented per API documentation of
* [EMAIL PROTECTED] java.util.Map.Entry#equals(Object)}
*/
- public boolean equals(Object o) {
- if( o == null ) return false;
+ public final boolean equals(Object o) {
if( o == this ) return true;
if ( ! (o instanceof Map.Entry ) )
@@ -116,22 +135,18 @@
* Implemented per API documentation of
* [EMAIL PROTECTED] java.util.Map.Entry#hashCode()}
*/
- public int hashCode() {
+ public final int hashCode() {
return ( ( getKey() == null ? 0 : getKey().hashCode() ) ^
( getValue() == null ? 0 : getValue().hashCode() ) );
}
-
- // Map.Entry interface
- //-------------------------------------------------------------------------
-
/**
* Returns the key.
*
* @return the key
*/
- public Object getKey() {
+ public final Object getKey() {
return key;
}
@@ -144,29 +159,29 @@
return value;
}
- // Properties
- //-------------------------------------------------------------------------
- /**
- * Sets the key. This method does not modify any map.
- *
- * @param key the new key
- */
- public void setKey(Object key) {
- this.key = key;
- }
-
/**
* Note that this method only sets the local reference inside this object and
- * does not modify the original Map.
+ * does not modify any Map.
*
* @return the old value of the value
* @param value the new value
+ * @throws IllegalArgumentException if value is this object. A Map.Entry may not
contain
+ * itself as a value because Map.Entry's required #hashCode implementation will
+ * enter an infinite recursion.
*/
public Object setValue(Object value) {
+ if (value == this)
+ throw new IllegalArgumentException("A Map.Entry may not contain itself
as a value.");
+
Object answer = this.value;
this.value = value;
return answer;
}
+
+ public String toString()
+ {
+ return new
StringBuffer().append(key).append('=').append(value).toString();
+ }
}
Index: TestAll.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons/collections/src/test/org/apache/commons/collections/TestAll.java,v
retrieving revision 1.47
diff -u -r1.47 TestAll.java
--- TestAll.java 20 Sep 2003 16:58:19 -0000 1.47
+++ TestAll.java 25 Sep 2003 05:12:58 -0000
@@ -105,7 +105,9 @@
suite.addTest(TestFastTreeMap1.suite());
suite.addTest(TestHashBag.suite());
suite.addTest(TestIteratorUtils.suite());
+ suite.addTest(TestKeyValuePair.suite());
suite.addTest(TestLRUMap.suite());
+ suite.addTest(TestMapEntry.suite());
suite.addTest(TestMultiHashMap.suite());
suite.addTest(TestMultiKey.suite());
suite.addTest(TestNodeCachingLinkedList.suite());
/*
* $Header:
x:/apps/cvsnt/cvs_repository/main/notifyingcollections/src/test/org/apache/commons/collections/TestKeyValueRecord.java,v
1.1 2003/09/20 22:00:46 otoolen Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.collections;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
*
* @author Neil O'Toole
*/
public class TestKeyValuePair extends TestCase
{
private final String key = "name";
private final String value = "duke";
public TestKeyValuePair(String testName)
{
super(testName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(TestKeyValuePair.class);
}
public static Test suite()
{
return new TestSuite(TestKeyValuePair.class);
}
public void testAccessorsAndMutators()
{
KeyValuePair kv = new KeyValuePair();
kv.setKey(key);
assertTrue(kv.getKey() == key);
kv.setValue(value);
assertTrue(kv.getValue() == value);
// check that null doesn't do anything funny
kv.setKey(null);
assertTrue(kv.getKey() == null);
kv.setValue(null);
assertTrue(kv.getValue() == null);
}
public void testSelfReferenceHandling()
{
// test that #setKey and #setValue do not permit
// the KVP to contain itself (and thus cause infinite recursion
// in #hashCode and #toString)
KeyValuePair kv = new KeyValuePair();
try
{
kv.setKey(kv);
fail("Should throw an IllegalArgumentException");
}
catch(IllegalArgumentException iae)
{
// expected to happen...
// check that the KVP's state has not changed
assertTrue(kv.getKey() == null && kv.getValue() == null);
}
try
{
kv.setValue(kv);
fail("Should throw an IllegalArgumentException");
}
catch(IllegalArgumentException iae)
{
// expected to happen...
// check that the KVP's state has not changed
assertTrue(kv.getKey() == null && kv.getValue() == null);
}
}
public void testConstructors()
{
// 1. test default constructor
KeyValuePair kv = new KeyValuePair();
assertTrue(kv.getKey() == null && kv.getValue() == null);
// 2. test key-value constructor
kv = new KeyValuePair(key, value);
assertTrue(kv.getKey() == key && kv.getValue() == value);
// 3. test copy constructor
KeyValuePair kv2 = new KeyValuePair(kv);
assertTrue(kv2.getKey() == key && kv2.getValue() == value);
// test that the KVPs are independent
kv.setKey(null);
kv.setValue(null);
assertTrue(kv2.getKey() == key && kv2.getValue() == value);
// 4. test Map.Entry constructor
Map map = new HashMap();
map.put(key, value);
Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
kv = new KeyValuePair(entry);
assertTrue(kv.getKey() == key && kv.getValue() == value);
// test that the KVP is independent of the Map.Entry
entry.setValue(null);
assertTrue(kv.getValue() == value);
}
public void testEqualsAndHashCode()
{
// 1. test with object data
KeyValuePair kv = new KeyValuePair(key, value);
KeyValuePair kv2 = new KeyValuePair(key, value);
assertTrue(kv.equals(kv));
assertTrue(kv.equals(kv2));
assertTrue(kv.hashCode() == kv2.hashCode());
// 2. test with nulls
kv = new KeyValuePair();
kv2 = new KeyValuePair();
assertTrue(kv.equals(kv));
assertTrue(kv.equals(kv2));
assertTrue(kv.hashCode() == kv2.hashCode());
}
public void testToString()
{
KeyValuePair kv = new KeyValuePair(key, value);
assertTrue(kv.toString().equals(kv.getKey() + "=" + kv.getValue()));
// test with nulls
kv = new KeyValuePair();
assertTrue(kv.toString().equals(kv.getKey() + "=" + kv.getValue()));
}
public void testToMapEntry()
{
KeyValuePair kv = new KeyValuePair(key, value);
Map map = new HashMap();
map.put(kv.getKey(), kv.getValue());
Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
assertTrue(entry.equals(kv.toMapEntry()));
assertTrue(entry.hashCode() == kv.hashCode());
}
}
/*
* $Header:
x:/apps/cvsnt/cvs_repository/main/notifyingcollections/src/test/org/apache/commons/collections/TestKeyValueRecord.java,v
1.1 2003/09/20 22:00:46 otoolen Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.collections;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
*
* @author Neil O'Toole
*/
public class TestMapEntry extends TestCase
{
private final String key = "name";
private final String value = "duke";
public TestMapEntry(String testName)
{
super(testName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(TestMapEntry.class);
}
public static Test suite()
{
return new TestSuite(TestMapEntry.class);
}
/**
* Make an instance of Map.Entry with the default (null) key and value.
* Subclasses should override this method to return a Map.Entry
* of the type being tested.
*/
public Map.Entry makeMapEntry()
{
return new DefaultMapEntry();
}
/**
* Make an instance of Map.Entry with the specified key and value.
* Subclasses should override this method to return a Map.Entry
* of the type being tested.
*/
public Map.Entry makeMapEntry(Object key, Object value)
{
return new DefaultMapEntry(key, value);
}
public Map.Entry makeKnownMapEntry()
{
return makeKnownMapEntry(null, null);
}
public Map.Entry makeKnownMapEntry(Object key, Object value)
{
Map map = new HashMap(1);
map.put(key, value);
Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
return entry;
}
public void testAccessorsAndMutators()
{
Map.Entry entry = makeMapEntry(key, value);
assertTrue(entry.getKey() == key);
entry.setValue(value);
assertTrue(entry.getValue() == value);
// check that null doesn't do anything funny
entry = makeMapEntry(null, null);
assertTrue(entry.getKey() == null);
entry.setValue(null);
assertTrue(entry.getValue() == null);
}
public void testSelfReferenceHandling()
{
// test that #setValue does not permit
// the MapEntry to contain itself (and thus cause infinite recursion
// in #hashCode and #toString)
Map.Entry entry = makeMapEntry();
try
{
entry.setValue(entry);
fail("Should throw an IllegalArgumentException");
}
catch(IllegalArgumentException iae)
{
// expected to happen...
// check that the KVP's state has not changed
assertTrue(entry.getKey() == null && entry.getValue() == null);
}
}
/**
* Subclasses should override this method.
*
*/
public void testConstructors()
{
// 1. test default constructor
Map.Entry entry = new DefaultMapEntry();
assertTrue(entry.getKey() == null && entry.getValue() == null);
// 2. test key-value constructor
entry = new DefaultMapEntry(key, value);
assertTrue(entry.getKey() == key && entry.getValue() == value);
// 3. test copy constructor
Map.Entry entry2 = new DefaultMapEntry(entry);
assertTrue(entry2.getKey() == key && entry2.getValue() == value);
// test that the objects are independent
entry.setValue(null);
assertTrue(entry2.getValue() == value);
}
public void testEqualsAndHashCode()
{
// 1. test with object data
Map.Entry e1 = makeMapEntry(key, value);
Map.Entry e2 = makeKnownMapEntry(key, value);
assertTrue(e1.equals(e1));
assertTrue(e2.equals(e1));
assertTrue(e1.hashCode() == e2.hashCode());
// 2. test with nulls
e1 = makeMapEntry();
e2 = makeKnownMapEntry();
assertTrue(e1.equals(e1));
assertTrue(e2.equals(e1));
assertTrue(e1.hashCode() == e2.hashCode());
}
public void testToString()
{
Map.Entry entry = makeMapEntry(key, value);
assertTrue(entry.toString().equals(entry.getKey() + "=" +
entry.getValue()));
// test with nulls
entry = makeMapEntry();
assertTrue(entry.toString().equals(entry.getKey() + "=" +
entry.getValue()));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]