views:

99

answers:

4

If an object holds a unique primary key, what interfaces does it need to implement in order to be collection friendly especially in terms of being efficiently sortable, hashable, etc...?

If the primary key is a string, how are these interfaces best implemented?

Thanks!

+11  A: 

You must implement equals, hashCode, and (after implementing the Comparable interface) compareTo.

In each case, since you have a string which is a primary key, you may consider simply dispatching these calls to your string. For example:

public class Friendly implements Comparable<Friendly>
{
    // presumably you've got other fields as well
    private String primaryKey;
    public Friendly(String primaryKey)
    {
        this.primaryKey = primaryKey;
    }

    public int compareTo(Friendly other)
    {
        return primaryKey.compareTo(other.primaryKey);
    }

    public int hashCode()
    {
        return primaryKey.hashCode();
    }

    public boolean equals(Object o)
    {
        return (o instanceof Friendly) && primaryKey.equals(((Friendly)o).primaryKey);
    }
}
Eli Courtwright
And make sure that compareTo conforms to the "equals" contract.
duffymo
And that equal objects have equal hashcodes.
CurtainDog
+5  A: 

Strings are already very well suited for hashing and comparison, so if your objects can truly be uniquely identified by strings then you are in good shape. Just make sure to implement the Comparable interface for sorting and override equals and hashCode (delegating to the primary key string) for hashing and you're good to go.

maerics
+3  A: 

If the primary key is an Object you need to decide if the sort order is based on the Object or the Object's Primary Key Object.

In either case, the item to be sorted should implement the Comparable interface, with a proper compareTo() method. Odds are excellent that means you'll have to override equals() and hashCode() too, as only some of the primary key Objects are likely to have proper default implementations.

If you want to sort based on some non-natural sort order, then also implement a few "extra" Comparators. Ordered Collections support alternative Comparators.

Edwin Buck
+3  A: 

You must override Object.equals() and Object.hashCode(), and also implement the Comparable interface. This will make your class fully "compliant" when doing any kind of sorting or hashing including using Collections.sort(), any Map class, or any Set class. If there's even a tiny chance that the class will be put in some sort of collection, then it should definitely implement all three of these methods.

public class A implements Comparable<A>{
  private String key;

  @Override
  public boolean equals(Object obj){
    if (this == obj) return true;
    if (!(obj instanceof A)) return false;

    A that = (A)obj;
    return this.key.equals(that.key);    
  }

  @Override
  public int hashCode(){
    return key.hashCode();
  }

  public int compareTo(A that){
    //returns -1 if "this" object is less than "that" object
    //returns 0 if they are equal
    //returns 1 if "this" object is greater than "that" object
    return this.key.compareTo(that.key);
  }
}

Keep in mind that if two objects are equal, then:

  1. their hash codes must also be equal and
  2. compareTo() must return 0.
Michael Angstadt