Reputation: 998
This is homework, so I would prefer some explanation rather than just giving me the answer.
I have a generic Pair class that can take any key value K, and any value V.
The goal is to write a generic method:
public static <...> Collection<Pair<...>> sortPairCollection(Collection <Pair<....>> col)
The only other guideline is that the K type must implement Comparable<...>.
After some digging, I saw people recommend something like this:
public static Collection<Pair<?,?>> sortPairCollection(Collection<Pair<?,?>> col)
{
Collections.sort(col, new Comparator<Pair<?,?>>(){
@Override
public int compare(Pair<?, ?> x, Pair<?, ?> y) {
return (Integer)x.v() - (Integer)y.v();
}
});
}
But that doesn't work for me, I get an error that says the sort method is not applicable to those parameters. I don't really know where to go from here.
Upvotes: 2
Views: 825
Reputation: 1
Here is the complete program:
public static <K extends Comparable<? super K>, V extends Comparable<? super V>> void sortPairCollection(List<Pair<K, V>> col){
Collections.sort(col, new Comparator<Pair<K,V>>(){
public int compare(Pair<K, V> o1, Pair<K, V> o2) {
int keyflag = o1.getValue().compareTo(o2.getValue()) == 0 ? o1.getKey().compareTo(o2.getKey()): o1.getValue().compareTo(o2.getValue()) ;
return keyflag;
}});
}
Upvotes: -1
Reputation: 37665
Collections.sort
only works on List
instances, not on general Collections
. It does not make sense to sort a HashSet
for example.
Secondly, due to arithmetic overflow, you should avoid using subtraction in a comparator like that. It is always better to use Integer.compare
.
Also, a method with return type Collection<Pair<?,?>>
must return something. You could return col
, but as you are mutating col
it makes more sense to make the method void
.
Another point is that it looks like your method will throw a ClassCastException
unless the second type parameter is Integer
(I am assuming v()
has return type V
). If this is the case, there is no point writing your method for Pair<?, ?>
as you could just use Pair<?, Integer>
.
Finally, due to the way generics work in Java, you won't actually be able to pass in a List<Pair<String, Integer>>
with your current signature, because a List<Pair<String, Integer>>
is not a List<Pair<?, Integer>>
(see this question or this one). If you want to be able to do that, the argument should have type List<? extends Pair<?, Integer>>
.
Edit
I now realise that I haven't really answered the question. The idea is not to mutate the original collection, but return a new one. Also the sorting should be done by key, not value, because K
must implement Comparable
.
In order to use the compareTo
method, you need to indicate that K extends Comparable
. The way to do this is to use the signature
public static <K extends Comparable<? super K>, V> Collection<Pair<K, V>> sortPairCollection(Collection<Pair<K, V>> col)
This is a bit of a mouthful - generics have significantly increased the complexity of method signatures.
K extends Comparable<? super K>
says that K
s can be compared with other K
s.
You will still need to use a List
though. You could use the ArrayList
constructor that accepts a Collection
.
As requested, I'll leave it up to you to write the correct code.
Upvotes: 6