Making a generic comparator class [closed]

2020-06-09 06:48发布

问题:

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 7 years ago.

I'm trying to make a comparator that can take any type of an element to compare. I'm unsure about how to create the class. I just want it to compare two elements of the same type (But whatever type the client gives it, ex: Integer, String, Double, etc...) to see which one is greater then the other.

public class InsertionComparator implements Comparator<T>
{
/**
 * Compares two elements.
 * 
 * @param  f1  The first element you want to compare.
 * @param  f2  The second element you want to compare.
 * @return  -1,0,1  Whether or not one is greater than, less than,
 * or equal to one another.
 */
public int compare(<T> element1,<T> element2)
{
    if(element1 < element2)
    {
        return -1;
    }
    else
    {
        if(element1 > element2)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    } 
}
}

Please help, thank you!

回答1:

The closest thing you can do to this is a Comparator that can compare any objects that implement the Comparable interface:

class NaturalComparator<T extends Comparable<T>> implements Comparator<T> {
  public int compare(T a, T b) {
    return a.compareTo(b);
  }
}

That's really the closest you can do: only Comparable objects have the "natural ordering" you're trying to model here. But generally, once you have Comparable objects, you don't necessarily need a Comparator: for example, Collections.sort can take either a List with a Comparator, or a List with Comparable elements.



回答2:

  1. You can't write a single comparator for everything without some assumptions on what the types will be. What do you do with custom classes? How can you decide which one is greater than the other? For more classes in the wild, a comparator does not make sense.

  2. On the other hand, if you restrict yourself to String, Integer, Double, then they are Comparable and you can simply write the comparator with the compareTo() method:

    public int compare(T element1,T element2)
    {
        return element1.compareTo(element2);
    }
    

but then you would simply use the natural order of elements, and it would defeat the purpose of using a comparator. You usually don't need one in these cases.



回答3:

I don't know if this is necessarily useful, but it isn't possible to implement a meaningful generic comparator.

Thanks to the reflection interface, you could, for example, order objects by their classname. Or perhaps even in some manner by their class hierarchy. Children after parents, for example.

Or you could sort them based on what their toString() method produces. Or hashCode(). Every object has them, after all.

Whatever you do, remember to consider that either element could be null.

I think we need to know what you need this generic comparator for.