5

Suppose the following generic class with 2 types T, U

public class Pair<T, U> implements Comparable<T, U>  { //Error 1

   private final T first;
   private final U second;

   public Pair(T first_, U second_) {
      first = first_;
      second = second_;}

   public T getFirst() { return first; }
   public U getSecond() { return second; }
}

and the list of its items

List<Pair<Integer, Integer>> = new ArrayList<>() 

that need to be sorted according to the first/second attribute. Unfortunately, the class definition contains some issue, the following error appears:

Error 1: wrong number of type arguments

How to design the comparator class? This code is probably completely wrong

public class SortBySecond implements Comparable <Pair <T, U>> {

    public int compare(final Pair<T, U> p1, final Pair<T, U> p2) //Error 2
    {
        return t1.getSecond().compareTo(t2.getSecond()); //Updated comparator
    }
}

Error 2 : Can not find symbols T, U, V

Thanks for your help.

8
  • 1
    I don't think you can compare generic types with < and >, those only work for primitive types. Instead try something like return p1.getSecond().compareTo(p2.getSecond());. Commented Sep 12, 2019 at 19:18
  • How do you want to compare two pairs? Commented Sep 12, 2019 at 19:18
  • "that need to be sorted according to the first/second attribute" do you mean that it first needs to be sorted by the first attribute. If the first attribute are the same, sort it by the second one? Commented Sep 12, 2019 at 19:20
  • 1
    I wouldn't have a generic Pair class implement Comparable. Who knows if T or U are comparable? Leave it up to the user to create a custom Comparator if they want to sort their pairs, that way they can decide whether to sort by the first field, the second, combine them, or whatever. Commented Sep 12, 2019 at 19:22
  • @azurefrog: The comparator has been updated according to your recommendation. Commented Sep 12, 2019 at 19:25

2 Answers 2

5

Your Pair class should implement Comparable<Pair<T, U>> instead of Comparable<T, U>, which is a type that does not exist. You should also make sure that T and U are comparable.

There are lots of useful methods in the Comparator interface to help you compare things. You can use them to implement Comparable<Pair<T, U>>. In fact, you don't need to implement Comparable to sort the list. You only need to create a Comparator!

Here's how to implement Comparable:

class Pair<T extends Comparable<T>, U extends Comparable<U>> implements Comparable<Pair<T, U>> {
    public int compare(final Pair<T, U> p1, final Pair<T, U> p2)
    {
        // this first compares the first field. If the first fields are the same, the second fields are compared
        // If you have a different requirement, implement it accordingly.
        return Comparator.comparing(Pair::getFirst).thenComparing(Pair::getSecond).compare(p1, p2);
    }
}

To sort your list, do:

list.sort(Comparator.comparing(Pair::getFirst).thenComparing(Pair::getSecond));

To sort your list with only the second field, do:

list.sort(Comparator.comparing(Pair::getSecond));
Sign up to request clarification or add additional context in comments.

1 Comment

"In fact, you don't need to implement Comparable to sort the list." Yes but overall you want to implement Comparable only if you have a natural order. And here it is clearly not the case, so Comparator makes more sense.
1

You should make sure that your T and U types extend Comparable and make your Pair class implement Comparable<Pair<T,U>> :

public class Pair<T extends Comparable<T>, U extends Comparable<U>> implements Comparable<Pair<T,U>>  {

        private final T first;
        private final U second;

        public Pair(T first_, U second_) {
            first = first_;
            second = second_;}

        public T getFirst() { return first; }
        public U getSecond() { return second; }

        @Override
        public int compareTo(Pair<T, U> o) {
            return this.second.compareTo(o.second);
        }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.