Search code examples
javacomparatorcomparable

Need to add Comparable without modifying the class that is comparing


Code:

LinkedBinarySearchTree <Pair<String, Integer>> at = new LinkedBinarySearchTree<>();
Pair<String, Integer> p = new Pair<>(str, dni);
at.insert(p);

Pair is a class that has been given to me, it isn't the java class Pair (idk if java has a default pair class but just in case it has one, this one isn't that).

The class pair doesn't have a compareTo defined in it and the method insert uses the compareTo at some point and when it does it crashes.

I need to implement the abstract class Comparable and override the method compareTo in the class from the outside, without modifying the code of the class Pair, which means I have to do it from the "outside".

Is there a way to do this?

This is what I did previously:

public class MyComparator implements Comparator <Pair<String, Integer>> {
        @Override
        public int compare(Pair<String, Integer> o1, Pair<String, Integer> o2) {
           final Collator instance = Collator.getInstance();
            instance.setStrength(Collator.NO_DECOMPOSITION);


        if (!o1.getFirst().equals(o2.getFirst())){
            return o1.getFirst().compareTo(o2.getFirst());
        } else {
            return o1.getSecond().compareTo(o2.getSecond());
        }
    }
}

But it doesn't work with Comparator, it has to be Comparable for some reason and I don't know how to do it because I can't refer (this):

public class MyComparable implements Comparable <Pair<String, Integer>> {
        @Override
        public int compareTo(Pair<String, Integer> o) {
           final Collator instance = Collator.getInstance();
            instance.setStrength(Collator.NO_DECOMPOSITION);

        //I can't use "this" here because ovbiously I'm not inside the class Pair so I don't know how to do it
        if (!this.getFirst().equals(o.getFirst())){   //I can't use "this"
            return this.getFirst().compareTo(o.getFirst());
        } else {
            return this.getSecond().compareTo(o.getSecond());
        }
    }
}

I need help please I've been trying to find an answer by myself and I'm out of ideas... I'm sorry if this question is too easy or unhelpful but I'm kinda struggling here :/.

 

  EDIT: I debugged the program and this is where it crashes, that's why I think I need the Comparable:

public class DefaultComparator<E> implements Comparator<E> {
    @Override
    public int compare(E a, E b) throws ClassCastException {
        return ((Comparable<E>) a).compareTo(b); //here
    }
}

Solution

  • Could you possibly extend Pair with you own class that also implements Comparable and use that?

    public class MyPair<T, O> extends Pair<T, O> implements Comparable<MyPair<T, O>> {
        @Override
        public int compareTo(MyPair<T, O> other) {
               //logic to compare
        }
    }
    

    and then use that

    LinkedBinarySearchTree <MyPair<String, Integer>> at = new LinkedBinarySearchTree<>();
    

    Edit based on comments: If you know the types of objects used in the Pair are themselves Comparable then you can use bounded generic parameters. So the example above becomes:

    public class MyPair<T extends Comparable<T>, O extends Comparable<O>> extends Pair<T, O> implements Comparable<MyPair<T, O>> {
        @Override
        public int compareTo(MyPair<T, O> other) {
               //Now the compiler knows that T and O types are Comparable (that 
               //is they implement the Comparable interface) and 
               //this means their compareTo() can be used
    
               return this.getFirst().compareTo(other.getFirst()); 
        }
    }