Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: sorting a generic class with two types

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.

like image 614
justik Avatar asked Sep 12 '19 19:09

justik


1 Answers

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));
like image 127
Sweeper Avatar answered Sep 30 '22 09:09

Sweeper