Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4890211

(coll) Collections.ReverseOrder.equals method is lacking

XMLWordPrintable

      Name: gm110360 Date: 07/14/2003


      FULL PRODUCT VERSION :
      java version "1.4.0_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
      Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)

      also:

      java version "1.3.1_04"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_04-b02)
      Java HotSpot(TM) Client VM (build 1.3.1_04-b02, mixed mode)

      FULL OPERATING SYSTEM VERSION :

      glibc: glibc-2.2.5-42
      Kernal: Linux 2.4.18-18-7.x #1 Wed Nov 13 20:29:30 EST 2002
      i686
      distro: redhat-release

      ADDITIONAL OPERATING SYSTEMS :

      (seems like a pure java issue to me)

      A DESCRIPTION OF THE PROBLEM :
      Collections.reverseOrder().equals(deserialize(serialize
      (Collections.reverseOrder()) returns false.

      The JavaDocs for java.util.Comparator.equals suggests (but
      doesn't strictly require):

      "[T]his method can return true only if the specified Object
      is also a comparator and it imposes the same ordering as
      this comparator. Thus comp1.equals(comp2) implies that sgn
      (comp1.compare(o1,o2)) == sgn(comp2.compare(o1,o2)) for
      every object reference o1 and o2."

      The java.util.Collections.reverseOrder method returns a
      Comparator that could readily support this "soft contract",
      but doesn't when serialized, deserialized and compared back
      to itself.

      See the sample unit test below.

      Overriding Object.equals would allow
      Collections.ReverseComparator to support this case as
      well. Something like this:

      public boolean equals(Object that) {
        return (that == this ||
               that instanceof Collections.ReverseComparator);
      }

      should suffice, since Collections.ReverseComparator is
      final (although I suppose it is still possible for
      instanceof to fail if "this" and "that" were loaded via
      different ClassLoaders).

      That Comparator suggests implementations should be
      Serializable, and that ReverseComparator is itself
      Serializable suggests that this problem isn't as obscure as
      it might at first seem.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compare two distinct instances of
      Collections.ReverseComparator and compare them using the
      equals method.

      One way to get two distinct instances is to serialize and
      then deserialize a single instance. See sample code below.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Collections.reverseOrder().equals(deserialize(serialize
      (Collections.reverseOrder()) should return true.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.Collections;
      import java.util.Comparator;
      import junit.framework.*;

      public class TestReverseOrder extends TestCase {
        public TestReverseOrder(String name) {
          super(name);
        }

        public static Test suite() {
          return new TestSuite(TestReverseOrder.class);
        }
          
        public void testEqualsDeserializedInstance() throws Exception {
          // obtain an instance of Collections.ReverseOrder
          Comparator comp1 = Collections.reverseOrder();

          // note that it is equal to itself
          assertTrue( "equals should be reflexive", comp1.equals(comp1) );
          // or assertEquals(comp1,comp1);

          // serialize it
          ByteArrayOutputStream buffer = new ByteArrayOutputStream();
          ObjectOutputStream out = new ObjectOutputStream(buffer);
          out.writeObject(comp1);

          // deserialize it
          ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream
      (buffer.toByteArray()))
          Comparator comp2 = (Comparator)(in.readObject());

          // note that comp1 is not equal to its deserialized clone
          assertEquals( "should equal deserialized clone", comp1.equals(comp2) );
          // or assertEquals(comp1,comp2);
        }
      }
      ---------- END SOURCE ----------
      (Incident Review ID: 179731)
      ======================================================================

            martin Martin Buchholz
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: