Thursday, January 24, 2013

BUG REPORT: Map's equals and hashCode methods.

Reading through Apex Developer's Guide (winter 13).  There is a new section for Winter 13 that talks about how you can compare if two custom Apex classes are equal or not.  The bug is not directly related to the equals and hashCode methods, but the bug is introduced here because from Winter 13, you are allowed to use non-primitive values as keys in maps.

You can find the documentation at this page:
http://www.salesforce.com/us/developer/docs/apexcode/Content/langCon_apex_collections_maps_keys_userdefined.htm

The following is the definition of PairNumbers class.

public class PairNumbers 
{
  Integer x,y;
  public PairNumbers(Integer a, Integer b) 
  {
    x=a;
    y=b;
  }

  public Boolean equals(Object obj) 
  {
    if (obj instanceof PairNumbers) 
    {
      PairNumbers p = (PairNumbers)obj;
      return ((x==p.x) && (y==p.y));
    }
    return false;
  }

  public Integer hashCode() 
  {
    return (31 * x) ^ y;
  }
}

The way it is implemented, if you create several instances of the class and add them to a Map collection, duplicate keys should be counted as one.    For example, if you have lines of code like this:

Map<PairNumbers, String> m = new Map<PairNumbers, String>();
PairNumbers p1 = new PairNumbers(1,2);
PairNumbers p2 = new PairNumbers(3,4);
PairNumbers p3 = new PairNumbers(1,2);
m.put(p1, 'first');
m.put(p2, 'second');
m.put(p3, 'third');


You should now have two elements in the collection m, that is because p3 have the same key as p1.  As a result, p3 replaces p1 in the collection m.

However, I noticed that, if I append the code with this line:
System.Debug(m.size());

and I run this code in Developer Console, the debug log will show 3 as the number of elements in the collection.

Strangely, when I run this on Eclipse, the debug log from there shows 2, which is the expected result.

This is a new feature introduced in Winter 13, and let's hope this gets fixed soon!


No comments:

Post a Comment

Please leave a comment.