I am trying to create a class implementing comparable. When all the class elements are integer, everything works well. When I go with String and use comparing
rather than comparingInt
, I receive the following errors.
Incorrect number of type arguments for generic method comparing(Function) of type Comparator; it cannot be parameterized with arguments
The type myClassdoes not define getFrom(T) that is applicable here
public class myClass implements Comparable<myClass> {
@Column (name="From")
private String from;
@Column (name="To")
private String to;
@Column (name="With")
private String with;
@Column (name="amount")
private int amount;
// Setters, getters, constructor
Comparator<myClass > comp = Comparator.<myClass>comparing(myClass::getFrom)
.thenComparing(myClass::getTo)
.thenComparing(myClass::getWith)
.thenComparingInt(myClass::getAmount);
@Override
public int compareTo(myClass o) {
return comp.compare(this, o);
}
}
Could someone point out what I might be missing here?
Comparator::comparing is a generic method that takes a function that is used to extract the value to be compared. You passed a method reference to myClass::getFrom
method which returns a String
and will be invoked on myClass
type object (through Function::apply
). That is why you have to pass generic types myClass
and String
.
However you could ommit those generic types because you are assigning your comparator to Comparator<myClass> comp
variable so types can be inferred automatically (also using types from your method reference used).
Looking further let's look at Comparator::comparing(Function)
method implementation :
static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> var0) {
Objects.requireNonNull(var0);
return (Comparator)((Serializable)((var1x, var2x) -> {
return ((Comparable)var0.apply(var1x)).compareTo(var0.apply(var2x));
}));
}
Here T
will be myClass
and U
will be String
. Function var0
will take myClass
as parameter and will return String
(so method reference to myClass::getFrom
will work here - generally it will be like invoking getFrom
on myClass
object). Actually as you can see this method will return a Comparator
as a lambda function which will use function var0
to extract values from var1x
and var2x
(both of them will be myClass
types). For me it looks a bit like a closure.