6

I found this comment on can StringBuffer objects be keys in TreeSet in Java?

"There are 2 identifying strategies used with Maps in Java (more-or-less).

Hashing: An input "Foo" is converted into a best-as-possible attempt to generate a number that uniquely accesses an index into an array. (Purists, please don't abuse me, I am intentionally simplifying). This index is where your value is stored. There is the likely possibility that "Foo" and "Bar" actually generate the same index value meaning they would both be mapped to the same array position. Obviously this can't work and so that's where the "equals()" method comes in; it is used to disambiguate

Comparison: By using a comparative method you don't need this extra disambiguation step because comparison NEVER produces this collision in the first place. The only key that "Foo" is equal to is "Foo". A really good idea though is if you can is to define "equals()" as compareTo() == 0; for consistency sake. Not a requirement."

my question is as follows: if my class implements comparable, then does it mean I dont have to override equals and hashcode method for using my objects as keys in Hash collections. eg

class Person implements Comparable<Person> {
     int id;
     String name;

     public Person(int id, String name) {
        this.id=id;
        this.name=name;
     }

    public int compareTo(Person other) {
      return this.id-other.id;
    }
}

Now, can I use my Person objects in Hashable collections?

Community
  • 1
  • 1
eagertoLearn
  • 9,772
  • 23
  • 80
  • 122

5 Answers5

6

The article you brough is talking on TreeSet. a tree set is a tree with each node has a place defined by it's value in compare to the other values already in the tree.

a hashTable stores key/value pairs in a hash table. When using a Hashtable, you specify an object that is used as a key, and the value that you want linked to that key. The key is then hashed, and the resulting hash code is used as the index at which the value is stored within the table.

the difference between Hashable and TreeSet is that treeset don't need hashCode, it just need to know if you need the take the item left or right in the tree. for that you can use Compare and nothing more.

in hashTable a compare will suffice, because it's build differently, each object get to his cell by hashing it, not by comparing it to the items already in the collection.

so the answer is no, you can' use Person in hashtable just with compareTo. u must override hashCode() and equals() for that

i also suggest you read this article on hashtables

No Idea For Name
  • 11,411
  • 10
  • 42
  • 70
2

HashTable does use equals and hashCode. Every class has those methods. If you don't implement them, you inherit them.

Whether you need to implement them depends on whether the inherited version is suitable for your purposes. In particular, since Person has no specified superclass, it inherits the Object methods. That means a Person object is equal only to itself.

Do you need two distinct Person objects to be treated as being equal as HashTable keys?

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
1

if my class implements comparable, then does it mean I dont have to override equals and hashcode method for using my objects as keys in Hash collections. eg

No, you still need to implement equals() and hashCode(). The methods perform very different functions and cannot be replaced by compareTo().

  • equals() returns a boolean based on equality of the object. This is usually identity equality and not field equality. This can be very different from the fields used to compare an object in compareTo(...) although if it makes sense for the entity, the equals() method can be:

    @Overrides
    public boolean equals(Object obj) {
         if (obj == null || obj.getClass() != getClass()) {
            return false;
         } else {
             return compareTo((Person)obj) == 0;
         }
    }
    
  • hashCode() returns an integer value for the instance which is used in hash tables to calculate the bucket it should be placed in. There is no equivalent way to get this value out of compareTo(...).

Gray
  • 115,027
  • 24
  • 293
  • 354
0

TreeSet needs Comparable, to add values to right or left of tree. HashMap needs equals() and Hashcode() methods that are available from Object Class but you have to override them for your purpose.

brain storm
  • 30,124
  • 69
  • 225
  • 393
0

If a class implements Comparable, that would suggest that instances of the class represent values of some sort; generally, when classes encapsulate values it will be possible for there to exist two distinct instances which hold the same value and should consequently be considered equivalent. Since the only way for distinct object instances to be considered equivalent is for them to override equals and hashCode, that would imply that things which implement Comparable should override equals and hashCode unless the encapsulated values upon which compare operates will be globally unique (implying that distinct instances should never be considered equivalent).

As a simple example, suppose a class includes a CreationRank field of type long; every time an instances is created, that member is set to a value fetched from a singleton AtomicLong, and Comparable uses that field to rank objects in the order of creation. No two distinct instances of the class will ever report the same CreationRank; consequently, the only way x.equals(y) should ever be true is if x and y refer to the same object instance--exactly the way the default equals and hashCode work.

BTW, having x.compare(y) return zero should generally imply that x.equals(y) will return true, and vice versa, but there are some cases where x.equals(y) may be false but x.compare(y) should nonetheless return zero. This may be the case when an object encapsulates some properties that can be ranked and others that cannot. Consider, for example, a hypohetical FutureAction type which encapsulates a DateTime and an implementation of a DoSomething interface. Such things could be ranked based upon the encapsulated date and time, but there may be no sensible way to rank two items which have the same date and time but different actions. Having equals report false while compare reports zero would make more sense than pretending that the clearly-non-equivalent items should be called "equal".

supercat
  • 77,689
  • 9
  • 166
  • 211