5

I try to use the containsKey method of a TreeMap, but somehow I have problems with it.

The objects stored in the treemap are defined such as equals() does not deliver the same result as compareTo(). this is intended.

However, the doc of java.util.Map says:

Returns true if this map contains a mapping for the specified key. More formally, returns true if and only if this map contains a mapping for a key k such that (key==null ? k==null : key.equals(k)). (There can be at most one such mapping.)

So I tried following:

c = someModifiedObject();
boolean t1 = sm.containsKey(c);
someObject c2 = new someObject();
boolean t2 = sm.containsKey(c2);
boolean t3 = c.equals(new Chain());
int t4 = c.compareTo(new Chain());

t1 is true, as the object is in the treemap. t3 is true, as t1 is equal t3 (regarding to the change equals() operator) t4 is false however, t2 is false as well. It seems that TreeMap uses compareTo() rather than equals() to determine if the object is present.

Is there another implementation of a sorted map, where i can use equals() to check if an object exists?

Lino
  • 19,604
  • 6
  • 47
  • 65
user3320142
  • 85
  • 1
  • 6
  • 2
    Use a Comparator that makes compareTo consistent with equals, or better, fix the compareTo method so that it is consistent with equals. A comparison method that is not consistent with equals should rather be implemented as a comparator, rather than the inherent natural ordering of the class. – JB Nizet Feb 17 '14 at 17:29
  • But the documentation also states: _"Many methods in Collections Framework interfaces are defined in terms of the equals method. For example, the specification for the containsKey(Object key) method says: "[too long to suit in the comment, but it's the def you gave]" This specification should not be construed to imply that invoking Map.containsKey with a non-null argument key will cause key.equals(k) to be invoked for any key k. Implementations are free to implement optimizations whereby the equals invocation is avoided, for example, by first comparing the hash codes of the two keys."_ – Alexis C. Feb 17 '14 at 17:30
  • Why in &deity's green earth would you want `compareTo` and `equals` to not respond equivalently??? (And keep in mind that any ordered set will use relative compares to establish the relative position of entities in the set, so `compareTo` is naturally used. You'd need to use an unordered set for `equals` to be "logical".) – Hot Licks Feb 17 '14 at 18:37
  • @HotLicks: Suppose a class has two fields of type `BigDecimal`, and wants to sort by the first and sub-sort by the second (for values where the first field matches). To allow (1.00, 2.0) to sort between (1.0, 1.0) and (1.0, 3.0), it's necessary that the relational comparator for `BigDecimal` ignore the precision [number of zeroes after the decimal]. On the other hand, even if 1.00 is neither above nor below 1.0, that doesn't mean that it should be considered equivalent. – supercat Feb 17 '14 at 21:58
  • @supercat - compareTo and equals should be consistent. If you need other compare operators name them differently. – Hot Licks Feb 17 '14 at 23:17
  • @HotLicks: The `compareTo` method is expected to be used for sorting; the `equals` method is used for testing equivalence. The behaviors required for two jobs will *naturally* coincide to a significant degree, but when they diverge it's better for `compareTo` to behave in the manner most suitable for sorting, and `equals` to behave in the manner most suitable for equivalence testing, than to have either manner behave in a manner which is not really suitable for its primary task. – supercat Feb 17 '14 at 23:26
  • They shouldn't diverge. – Hot Licks Feb 17 '14 at 23:28
  • containsKey will use compareTo to find candidate keys. It returns true when the candidate key's compareTo == 0 _and_ it equals to the sought key. Maybe you have a case for [floorEntry(key)](https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html#floorEntry-K-) or such. – Joop Eggen Jan 30 '18 at 11:14

1 Answers1

0

While there is no standard java API to exactly get what you want you could create your own Comparator interface and then make your TreeMap implement this Comparator. You can override the compareTo() method to behave however you want (in your case, make it behave the same way as equals() method).

Ashish Kumar
  • 916
  • 2
  • 15
  • 32
ucsunil
  • 7,378
  • 1
  • 27
  • 32