You can create two different Pair classes, for example:
public class Pair<K, V> { protected final K key; protected final V value; public Pair(K key, V value) { this.key = key; this.value = value; } } public class ComparablePair<K extends Comparable<K>, V> extends Pair<K, V> implements Comparable<ComparablePair<K, V>> { public ComparablePair(K key, V value) { super(key, value); } @Override public int compareTo(ComparablePair<K, V> o) { return key.compareTo(o.key); } }
And limit Comparable trees to a second class. However, it looks cleaner (especially in Java-8) to use a disparate pair, but specify Comparator instead:
class MyTree<K, V> { final Comparator<K> comparator; public MyTree(Comparator<K> comparator) { this.comparator = comparator; } ... instead of k1.compareTo(k2) use comparator.compare(k1, k2) ... }
Thus, you achieve greater flexibility, since you can compare keys not only in the natural order, but also for any order. If you need a natural order, just use new MyTree<String, Integer>(Comparator.naturalOrder()); . This way you will have a compile time check to see if your key type is comparable.
source share