You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Neil O'Toole <ne...@users.sourceforge.net> on 2003/09/22 06:22:06 UTC
[collections] Map.Entry and KeyValue
> > ** I had a swift look through [collections] and [lang], and didn't
> see
> > a simple KeyValuePair implementation... Have I missed this
> somewhere?
>
> DefaultMapEntry IIRC is the simple Map.Entry impl.
> Stephen
>
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 (and there
are many cases where it is useful to extend a KeyValue class). In fact,
DefaultMapEntry (or at the very least its #equals and #hashcode
methods) should be declared final so that users won't make the mistake
of subclassing it.
DefaultMapEntry is not extendable because the #equals method is
contractually specified by Map.Entry to only evalute the members of
Map.Entry. A non-trivial subclass of DefaultMapEntry will add members
that will be used in #equals comparision. To make use of these members
in #equals will of course violate the Map.Entry#equals contract.
This non-extensibility property applies to any class that inherits or
implements an #equals method with a similar closed #equals contract,
and any such class should be declared final to prevent accidental
subclassing (or again, at the very least the #hashcode and #equals
methods should be declared final, though the user might just ignore
those methods, resulting in unfortunate code).
My suggested solution is to add a class "KeyValue.java" containing the
code from DefaultMapEntry, but not implementing Map.Entry.
DefaultMapEntry can then subclass KeyValue and implement Map.Entry, and
be declared final.
- Neil
Re: [collections] Map.Entry and KeyValue
Posted by Neil O'Toole <ne...@users.sourceforge.net>.
I believe that the test case for DefaultMapEntry will test by extension
test KeyValuePair??.. though we can simply subclass the test case also
- should we do this?
N.
--- Stephen Colebourne <sc...@btopenworld.com> wrote:
> I'm happy to add it....with a test case :-)
> Stephen
>
> ----- Original Message -----
> From: "Neil O'Toole" <ne...@users.sourceforge.net>
> > > My suggested solution is to add a class "KeyValue.java"
> containing
> > > the code from DefaultMapEntry, but not implementing Map.Entry.
> > > DefaultMapEntry can then subclass KeyValue and implement
> Map.Entry,
> > > and be declared final.
> >
> > Suggested solution attached (KeyValuePair.java and patch for
> > DefaultMapEntry.java). Note that:
> >
> > - The superflous null check is removed from DefaultMapEntry#equals
> > (instanceof checks for null).
> > - The DefaultMapEntry #equals and #hashCode methods are declared
> final.
> > The 'correct' approach is probably that the whole class should be
> > declared final - thoughts on this??.
> > - KeyValuePair has a toString() method.
> >
> > Unless there are objections, anyone want to add this to CVS?
> >
> > Neil
> >
> >
> > --- Neil O'Toole <ne...@users.sourceforge.net> wrote:
> > > > > ** I had a swift look through [collections] and [lang], and
> > > didn't
> > > > see
> > > > > a simple KeyValuePair implementation... Have I missed this
> > > > somewhere?
> > > >
> > > > DefaultMapEntry IIRC is the simple Map.Entry impl.
> > > > Stephen
> > > >
> > >
> > > 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 (and
> > > there
> > > are many cases where it is useful to extend a KeyValue class). In
> > > fact,
> > > DefaultMapEntry (or at the very least its #equals and #hashcode
> > > methods) should be declared final so that users won't make the
> > > mistake
> > > of subclassing it.
> > >
> > > DefaultMapEntry is not extendable because the #equals method is
> > > contractually specified by Map.Entry to only evalute the members
> of
> > > Map.Entry. A non-trivial subclass of DefaultMapEntry will add
> members
> > > that will be used in #equals comparision. To make use of these
> > > members
> > > in #equals will of course violate the Map.Entry#equals contract.
> > >
> > > This non-extensibility property applies to any class that
> inherits or
> > > implements an #equals method with a similar closed #equals
> contract,
> > > and any such class should be declared final to prevent accidental
> > > subclassing (or again, at the very least the #hashcode and
> #equals
> > > methods should be declared final, though the user might just
> ignore
> > > those methods, resulting in unfortunate code).
> > >
> > > My suggested solution is to add a class "KeyValue.java"
> containing
> > > the
> > > code from DefaultMapEntry, but not implementing Map.Entry.
> > > DefaultMapEntry can then subclass KeyValue and implement
> Map.Entry,
> > > and
> > > be declared final.
> > >
> > > - Neil
> > >
> > >
> > >
> > >
> ---------------------------------------------------------------------
> > > To unsubscribe, e-mail:
> commons-dev-unsubscribe@jakarta.apache.org
> > > For additional commands, e-mail:
> commons-dev-help@jakarta.apache.org
> > >
> >
>
>
>
----------------------------------------------------------------------------
> ----
>
>
> > /*
> > * $Header:
>
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/coll
> ections/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 apache@apache.org.
> > *
> > * 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;
> >
> >
> >
> > /**
> > * A simple key-value pair.
> > *
> > * @since Commons Collections 3.0
> > * @version $Revision: $
> > *
> > * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
> > * @author <a href="mailto:mas@apache.org">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>DefaultMapEntry</Code> with a null
> key
> > * and null value.
> > */
> > public KeyValuePair() {
> > }
> >
> > /**
> > * Constructs a new <Code>DefaultMapEntry</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;
> > }
> >
> >
> > /**
> > * 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 e2 = (KeyValuePair) o;
> > return ((getKey() == null ?
> > e2.getKey() == null :
> getKey().equals(e2.getKey())) &&
> > (getValue() == null ?
> > e2.getValue() == null :
> getValue().equals(e2.getValue())));
> > }
> >
> >
> >
> > 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
> > */
> > public void setKey(Object key) {
> > this.key = key;
> > }
> >
> > /**
> > * Sets the value.
> > *
> > * @return the old value of the value
> > * @param value the new value
> > */
> > public Object setValue(Object value) {
> > Object answer = this.value;
> > this.value = value;
> > return answer;
> > }
> >
> > 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/coll
> ections/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 23 Sep 2003 02:00:14 -0000
> > @@ -67,13 +67,10 @@
> > *
> > * @author <a href="mailto:jstrachan@apache.org">James
> Strachan</a>
> > * @author <a href="mailto:mas@apache.org">Michael A. Smith</a>
> > + * @author Neil O'Toole
> > */
> > -public class DefaultMapEntry implements Map.Entry {
> > +public class DefaultMapEntry extends KeyValuePair implements
> Map.Entry {
> >
> > - /** The key */
> > - private Object key;
> > - /** The value */
> > - private Object value;
> >
> > /**
> > * Constructs a new <Code>DefaultMapEntry</Code> with a null
> key
> > @@ -90,20 +87,18 @@
> > * @param value the value for the entry, may be null
> > */
> > public DefaultMapEntry(Object key, Object value) {
> > - this.key = key;
> > - this.value = value;
> > + super(key, value);
> > }
> >
> > /**
> > * Implemented per API documentation of
> > * {@link 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 ) )
> > - return false;
> > + if ( !(o instanceof Map.Entry ) ) return false;
> > +
> > Map.Entry e2 = (Map.Entry)o;
> > return ((getKey() == null ?
> > e2.getKey() == null :
> getKey().equals(e2.getKey())) &&
> > @@ -116,57 +111,12 @@
> > * Implemented per API documentation of
> > * {@link 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() {
> > - return key;
> > - }
> > -
> > - /**
> > - * Returns the value.
> > - *
> > - * @return the value
> > - */
> > - public Object getValue() {
> > - 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.
> > - *
> > - * @return the old value of the value
> > - * @param value the new value
> > - */
> > - public Object setValue(Object value) {
> > - Object answer = this.value;
> > - this.value = value;
> > - return answer;
> > - }
> >
> > }
> >
> >
>
>
>
----------------------------------------------------------------------------
> ----
>
>
> >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail:
> commons-dev-help@jakarta.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: [collections] Map.Entry and KeyValue
Posted by Neil O'Toole <ne...@users.sourceforge.net>.
I believe that the test case for DefaultMapEntry will test by extension
test KeyValuePair??.. though we can simply subclass the test case also
- should we do this?
N.
--- Stephen Colebourne <sc...@btopenworld.com> wrote:
> I'm happy to add it....with a test case :-)
> Stephen
>
> ----- Original Message -----
> From: "Neil O'Toole" <ne...@users.sourceforge.net>
> > > My suggested solution is to add a class "KeyValue.java"
> containing
> > > the code from DefaultMapEntry, but not implementing Map.Entry.
> > > DefaultMapEntry can then subclass KeyValue and implement
> Map.Entry,
> > > and be declared final.
> >
> > Suggested solution attached (KeyValuePair.java and patch for
> > DefaultMapEntry.java). Note that:
> >
> > - The superflous null check is removed from DefaultMapEntry#equals
> > (instanceof checks for null).
> > - The DefaultMapEntry #equals and #hashCode methods are declared
> final.
> > The 'correct' approach is probably that the whole class should be
> > declared final - thoughts on this??.
> > - KeyValuePair has a toString() method.
> >
> > Unless there are objections, anyone want to add this to CVS?
> >
> > Neil
> >
> >
> > --- Neil O'Toole <ne...@users.sourceforge.net> wrote:
> > > > > ** I had a swift look through [collections] and [lang], and
> > > didn't
> > > > see
> > > > > a simple KeyValuePair implementation... Have I missed this
> > > > somewhere?
> > > >
> > > > DefaultMapEntry IIRC is the simple Map.Entry impl.
> > > > Stephen
> > > >
> > >
> > > 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 (and
> > > there
> > > are many cases where it is useful to extend a KeyValue class). In
> > > fact,
> > > DefaultMapEntry (or at the very least its #equals and #hashcode
> > > methods) should be declared final so that users won't make the
> > > mistake
> > > of subclassing it.
> > >
> > > DefaultMapEntry is not extendable because the #equals method is
> > > contractually specified by Map.Entry to only evalute the members
> of
> > > Map.Entry. A non-trivial subclass of DefaultMapEntry will add
> members
> > > that will be used in #equals comparision. To make use of these
> > > members
> > > in #equals will of course violate the Map.Entry#equals contract.
> > >
> > > This non-extensibility property applies to any class that
> inherits or
> > > implements an #equals method with a similar closed #equals
> contract,
> > > and any such class should be declared final to prevent accidental
> > > subclassing (or again, at the very least the #hashcode and
> #equals
> > > methods should be declared final, though the user might just
> ignore
> > > those methods, resulting in unfortunate code).
> > >
> > > My suggested solution is to add a class "KeyValue.java"
> containing
> > > the
> > > code from DefaultMapEntry, but not implementing Map.Entry.
> > > DefaultMapEntry can then subclass KeyValue and implement
> Map.Entry,
> > > and
> > > be declared final.
> > >
> > > - Neil
> > >
> > >
> > >
> > >
> ---------------------------------------------------------------------
> > > To unsubscribe, e-mail:
> commons-dev-unsubscribe@jakarta.apache.org
> > > For additional commands, e-mail:
> commons-dev-help@jakarta.apache.org
> > >
> >
>
>
>
----------------------------------------------------------------------------
> ----
>
>
> > /*
> > * $Header:
>
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/coll
> ections/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 apache@apache.org.
> > *
> > * 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;
> >
> >
> >
> > /**
> > * A simple key-value pair.
> > *
> > * @since Commons Collections 3.0
> > * @version $Revision: $
> > *
> > * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
> > * @author <a href="mailto:mas@apache.org">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>DefaultMapEntry</Code> with a null
> key
> > * and null value.
> > */
> > public KeyValuePair() {
> > }
> >
> > /**
> > * Constructs a new <Code>DefaultMapEntry</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;
> > }
> >
> >
> > /**
> > * 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 e2 = (KeyValuePair) o;
> > return ((getKey() == null ?
> > e2.getKey() == null :
> getKey().equals(e2.getKey())) &&
> > (getValue() == null ?
> > e2.getValue() == null :
> getValue().equals(e2.getValue())));
> > }
> >
> >
> >
> > 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
> > */
> > public void setKey(Object key) {
> > this.key = key;
> > }
> >
> > /**
> > * Sets the value.
> > *
> > * @return the old value of the value
> > * @param value the new value
> > */
> > public Object setValue(Object value) {
> > Object answer = this.value;
> > this.value = value;
> > return answer;
> > }
> >
> > 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/coll
> ections/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 23 Sep 2003 02:00:14 -0000
> > @@ -67,13 +67,10 @@
> > *
> > * @author <a href="mailto:jstrachan@apache.org">James
> Strachan</a>
> > * @author <a href="mailto:mas@apache.org">Michael A. Smith</a>
> > + * @author Neil O'Toole
> > */
> > -public class DefaultMapEntry implements Map.Entry {
> > +public class DefaultMapEntry extends KeyValuePair implements
> Map.Entry {
> >
> > - /** The key */
> > - private Object key;
> > - /** The value */
> > - private Object value;
> >
> > /**
> > * Constructs a new <Code>DefaultMapEntry</Code> with a null
> key
> > @@ -90,20 +87,18 @@
> > * @param value the value for the entry, may be null
> > */
> > public DefaultMapEntry(Object key, Object value) {
> > - this.key = key;
> > - this.value = value;
> > + super(key, value);
> > }
> >
> > /**
> > * Implemented per API documentation of
> > * {@link 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 ) )
> > - return false;
> > + if ( !(o instanceof Map.Entry ) ) return false;
> > +
> > Map.Entry e2 = (Map.Entry)o;
> > return ((getKey() == null ?
> > e2.getKey() == null :
> getKey().equals(e2.getKey())) &&
> > @@ -116,57 +111,12 @@
> > * Implemented per API documentation of
> > * {@link 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() {
> > - return key;
> > - }
> > -
> > - /**
> > - * Returns the value.
> > - *
> > - * @return the value
> > - */
> > - public Object getValue() {
> > - 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.
> > - *
> > - * @return the old value of the value
> > - * @param value the new value
> > - */
> > - public Object setValue(Object value) {
> > - Object answer = this.value;
> > - this.value = value;
> > - return answer;
> > - }
> >
> > }
> >
> >
>
>
>
----------------------------------------------------------------------------
> ----
>
>
> >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail:
> commons-dev-help@jakarta.apache.org
>
Re: [collections] Map.Entry and KeyValue
Posted by Stephen Colebourne <sc...@btopenworld.com>.
I'm happy to add it....with a test case :-)
Stephen
----- Original Message -----
From: "Neil O'Toole" <ne...@users.sourceforge.net>
> > My suggested solution is to add a class "KeyValue.java" containing
> > the code from DefaultMapEntry, but not implementing Map.Entry.
> > DefaultMapEntry can then subclass KeyValue and implement Map.Entry,
> > and be declared final.
>
> Suggested solution attached (KeyValuePair.java and patch for
> DefaultMapEntry.java). Note that:
>
> - The superflous null check is removed from DefaultMapEntry#equals
> (instanceof checks for null).
> - The DefaultMapEntry #equals and #hashCode methods are declared final.
> The 'correct' approach is probably that the whole class should be
> declared final - thoughts on this??.
> - KeyValuePair has a toString() method.
>
> Unless there are objections, anyone want to add this to CVS?
>
> Neil
>
>
> --- Neil O'Toole <ne...@users.sourceforge.net> wrote:
> > > > ** I had a swift look through [collections] and [lang], and
> > didn't
> > > see
> > > > a simple KeyValuePair implementation... Have I missed this
> > > somewhere?
> > >
> > > DefaultMapEntry IIRC is the simple Map.Entry impl.
> > > Stephen
> > >
> >
> > 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 (and
> > there
> > are many cases where it is useful to extend a KeyValue class). In
> > fact,
> > DefaultMapEntry (or at the very least its #equals and #hashcode
> > methods) should be declared final so that users won't make the
> > mistake
> > of subclassing it.
> >
> > DefaultMapEntry is not extendable because the #equals method is
> > contractually specified by Map.Entry to only evalute the members of
> > Map.Entry. A non-trivial subclass of DefaultMapEntry will add members
> > that will be used in #equals comparision. To make use of these
> > members
> > in #equals will of course violate the Map.Entry#equals contract.
> >
> > This non-extensibility property applies to any class that inherits or
> > implements an #equals method with a similar closed #equals contract,
> > and any such class should be declared final to prevent accidental
> > subclassing (or again, at the very least the #hashcode and #equals
> > methods should be declared final, though the user might just ignore
> > those methods, resulting in unfortunate code).
> >
> > My suggested solution is to add a class "KeyValue.java" containing
> > the
> > code from DefaultMapEntry, but not implementing Map.Entry.
> > DefaultMapEntry can then subclass KeyValue and implement Map.Entry,
> > and
> > be declared final.
> >
> > - Neil
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >
>
----------------------------------------------------------------------------
----
> /*
> * $Header:
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/coll
ections/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 apache@apache.org.
> *
> * 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;
>
>
>
> /**
> * A simple key-value pair.
> *
> * @since Commons Collections 3.0
> * @version $Revision: $
> *
> * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
> * @author <a href="mailto:mas@apache.org">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>DefaultMapEntry</Code> with a null key
> * and null value.
> */
> public KeyValuePair() {
> }
>
> /**
> * Constructs a new <Code>DefaultMapEntry</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;
> }
>
>
> /**
> * 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 e2 = (KeyValuePair) o;
> return ((getKey() == null ?
> e2.getKey() == null : getKey().equals(e2.getKey())) &&
> (getValue() == null ?
> e2.getValue() == null :
getValue().equals(e2.getValue())));
> }
>
>
>
> 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
> */
> public void setKey(Object key) {
> this.key = key;
> }
>
> /**
> * Sets the value.
> *
> * @return the old value of the value
> * @param value the new value
> */
> public Object setValue(Object value) {
> Object answer = this.value;
> this.value = value;
> return answer;
> }
>
> 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/coll
ections/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 23 Sep 2003 02:00:14 -0000
> @@ -67,13 +67,10 @@
> *
> * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
> * @author <a href="mailto:mas@apache.org">Michael A. Smith</a>
> + * @author Neil O'Toole
> */
> -public class DefaultMapEntry implements Map.Entry {
> +public class DefaultMapEntry extends KeyValuePair implements Map.Entry {
>
> - /** The key */
> - private Object key;
> - /** The value */
> - private Object value;
>
> /**
> * Constructs a new <Code>DefaultMapEntry</Code> with a null key
> @@ -90,20 +87,18 @@
> * @param value the value for the entry, may be null
> */
> public DefaultMapEntry(Object key, Object value) {
> - this.key = key;
> - this.value = value;
> + super(key, value);
> }
>
> /**
> * Implemented per API documentation of
> * {@link 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 ) )
> - return false;
> + if ( !(o instanceof Map.Entry ) ) return false;
> +
> Map.Entry e2 = (Map.Entry)o;
> return ((getKey() == null ?
> e2.getKey() == null : getKey().equals(e2.getKey())) &&
> @@ -116,57 +111,12 @@
> * Implemented per API documentation of
> * {@link 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() {
> - return key;
> - }
> -
> - /**
> - * Returns the value.
> - *
> - * @return the value
> - */
> - public Object getValue() {
> - 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.
> - *
> - * @return the old value of the value
> - * @param value the new value
> - */
> - public Object setValue(Object value) {
> - Object answer = this.value;
> - this.value = value;
> - return answer;
> - }
>
> }
>
>
----------------------------------------------------------------------------
----
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: [collections] Map.Entry and KeyValue
Posted by Stephen Colebourne <sc...@btopenworld.com>.
I'm happy to add it....with a test case :-)
Stephen
----- Original Message -----
From: "Neil O'Toole" <ne...@users.sourceforge.net>
> > My suggested solution is to add a class "KeyValue.java" containing
> > the code from DefaultMapEntry, but not implementing Map.Entry.
> > DefaultMapEntry can then subclass KeyValue and implement Map.Entry,
> > and be declared final.
>
> Suggested solution attached (KeyValuePair.java and patch for
> DefaultMapEntry.java). Note that:
>
> - The superflous null check is removed from DefaultMapEntry#equals
> (instanceof checks for null).
> - The DefaultMapEntry #equals and #hashCode methods are declared final.
> The 'correct' approach is probably that the whole class should be
> declared final - thoughts on this??.
> - KeyValuePair has a toString() method.
>
> Unless there are objections, anyone want to add this to CVS?
>
> Neil
>
>
> --- Neil O'Toole <ne...@users.sourceforge.net> wrote:
> > > > ** I had a swift look through [collections] and [lang], and
> > didn't
> > > see
> > > > a simple KeyValuePair implementation... Have I missed this
> > > somewhere?
> > >
> > > DefaultMapEntry IIRC is the simple Map.Entry impl.
> > > Stephen
> > >
> >
> > 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 (and
> > there
> > are many cases where it is useful to extend a KeyValue class). In
> > fact,
> > DefaultMapEntry (or at the very least its #equals and #hashcode
> > methods) should be declared final so that users won't make the
> > mistake
> > of subclassing it.
> >
> > DefaultMapEntry is not extendable because the #equals method is
> > contractually specified by Map.Entry to only evalute the members of
> > Map.Entry. A non-trivial subclass of DefaultMapEntry will add members
> > that will be used in #equals comparision. To make use of these
> > members
> > in #equals will of course violate the Map.Entry#equals contract.
> >
> > This non-extensibility property applies to any class that inherits or
> > implements an #equals method with a similar closed #equals contract,
> > and any such class should be declared final to prevent accidental
> > subclassing (or again, at the very least the #hashcode and #equals
> > methods should be declared final, though the user might just ignore
> > those methods, resulting in unfortunate code).
> >
> > My suggested solution is to add a class "KeyValue.java" containing
> > the
> > code from DefaultMapEntry, but not implementing Map.Entry.
> > DefaultMapEntry can then subclass KeyValue and implement Map.Entry,
> > and
> > be declared final.
> >
> > - Neil
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >
>
----------------------------------------------------------------------------
----
> /*
> * $Header:
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/coll
ections/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 apache@apache.org.
> *
> * 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;
>
>
>
> /**
> * A simple key-value pair.
> *
> * @since Commons Collections 3.0
> * @version $Revision: $
> *
> * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
> * @author <a href="mailto:mas@apache.org">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>DefaultMapEntry</Code> with a null key
> * and null value.
> */
> public KeyValuePair() {
> }
>
> /**
> * Constructs a new <Code>DefaultMapEntry</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;
> }
>
>
> /**
> * 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 e2 = (KeyValuePair) o;
> return ((getKey() == null ?
> e2.getKey() == null : getKey().equals(e2.getKey())) &&
> (getValue() == null ?
> e2.getValue() == null :
getValue().equals(e2.getValue())));
> }
>
>
>
> 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
> */
> public void setKey(Object key) {
> this.key = key;
> }
>
> /**
> * Sets the value.
> *
> * @return the old value of the value
> * @param value the new value
> */
> public Object setValue(Object value) {
> Object answer = this.value;
> this.value = value;
> return answer;
> }
>
> 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/coll
ections/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 23 Sep 2003 02:00:14 -0000
> @@ -67,13 +67,10 @@
> *
> * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
> * @author <a href="mailto:mas@apache.org">Michael A. Smith</a>
> + * @author Neil O'Toole
> */
> -public class DefaultMapEntry implements Map.Entry {
> +public class DefaultMapEntry extends KeyValuePair implements Map.Entry {
>
> - /** The key */
> - private Object key;
> - /** The value */
> - private Object value;
>
> /**
> * Constructs a new <Code>DefaultMapEntry</Code> with a null key
> @@ -90,20 +87,18 @@
> * @param value the value for the entry, may be null
> */
> public DefaultMapEntry(Object key, Object value) {
> - this.key = key;
> - this.value = value;
> + super(key, value);
> }
>
> /**
> * Implemented per API documentation of
> * {@link 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 ) )
> - return false;
> + if ( !(o instanceof Map.Entry ) ) return false;
> +
> Map.Entry e2 = (Map.Entry)o;
> return ((getKey() == null ?
> e2.getKey() == null : getKey().equals(e2.getKey())) &&
> @@ -116,57 +111,12 @@
> * Implemented per API documentation of
> * {@link 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() {
> - return key;
> - }
> -
> - /**
> - * Returns the value.
> - *
> - * @return the value
> - */
> - public Object getValue() {
> - 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.
> - *
> - * @return the old value of the value
> - * @param value the new value
> - */
> - public Object setValue(Object value) {
> - Object answer = this.value;
> - this.value = value;
> - return answer;
> - }
>
> }
>
>
----------------------------------------------------------------------------
----
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: [collections] Map.Entry and KeyValue
Posted by Neil O'Toole <ne...@users.sourceforge.net>.
> My suggested solution is to add a class "KeyValue.java" containing
> the code from DefaultMapEntry, but not implementing Map.Entry.
> DefaultMapEntry can then subclass KeyValue and implement Map.Entry,
> and be declared final.
Suggested solution attached (KeyValuePair.java and patch for
DefaultMapEntry.java). Note that:
- The superflous null check is removed from DefaultMapEntry#equals
(instanceof checks for null).
- The DefaultMapEntry #equals and #hashCode methods are declared final.
The 'correct' approach is probably that the whole class should be
declared final - thoughts on this??.
- KeyValuePair has a toString() method.
Unless there are objections, anyone want to add this to CVS?
Neil
--- Neil O'Toole <ne...@users.sourceforge.net> wrote:
> > > ** I had a swift look through [collections] and [lang], and
> didn't
> > see
> > > a simple KeyValuePair implementation... Have I missed this
> > somewhere?
> >
> > DefaultMapEntry IIRC is the simple Map.Entry impl.
> > Stephen
> >
>
> 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 (and
> there
> are many cases where it is useful to extend a KeyValue class). In
> fact,
> DefaultMapEntry (or at the very least its #equals and #hashcode
> methods) should be declared final so that users won't make the
> mistake
> of subclassing it.
>
> DefaultMapEntry is not extendable because the #equals method is
> contractually specified by Map.Entry to only evalute the members of
> Map.Entry. A non-trivial subclass of DefaultMapEntry will add members
> that will be used in #equals comparision. To make use of these
> members
> in #equals will of course violate the Map.Entry#equals contract.
>
> This non-extensibility property applies to any class that inherits or
> implements an #equals method with a similar closed #equals contract,
> and any such class should be declared final to prevent accidental
> subclassing (or again, at the very least the #hashcode and #equals
> methods should be declared final, though the user might just ignore
> those methods, resulting in unfortunate code).
>
> My suggested solution is to add a class "KeyValue.java" containing
> the
> code from DefaultMapEntry, but not implementing Map.Entry.
> DefaultMapEntry can then subclass KeyValue and implement Map.Entry,
> and
> be declared final.
>
> - Neil
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>