Collections sort(ListT,Comparator? super T) method example
Building upon your existing Student class, this is how I usually do it, especially if I need more than one comparator.
public class Student implements Comparable<Student> {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + ":" + age;
}
@Override
public int compareTo(Student o) {
return Comparators.NAME.compare(this, o);
}
public static class Comparators {
public static Comparator<Student> NAME = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
};
public static Comparator<Student> AGE = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
};
public static Comparator<Student> NAMEANDAGE = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int i = o1.name.compareTo(o2.name);
if (i == 0) {
i = o1.age - o2.age;
}
return i;
}
};
}
}
Usage:
List<Student> studentList = new LinkedList<>();
Collections.sort(studentList, Student.Comparators.AGE);
EDIT
Since the release of Java 8 the inner class Comparators
may be greatly simplified using lambdas. Java 8 also introduces a new method for the Comparator
object thenComparing
, which removes the need for doing manual checking of each comparator when nesting them. Below is the Java 8 implementation of the Student.Comparators
class with these changes taken into account.
public static class Comparators {
public static final Comparator<Student> NAME = (Student o1, Student o2) -> o1.name.compareTo(o2.name);
public static final Comparator<Student> AGE = (Student o1, Student o2) -> Integer.compare(o1.age, o2.age);
public static final Comparator<Student> NAMEANDAGE = (Student o1, Student o2) -> NAME.thenComparing(AGE).compare(o1, o2);
}
Confusion about Collections.sort(ListT list, Comparator? super T c) example
for d1.age - d2.age
- if negative number, then d1 is logically less than d2 in sort order
- if positive, then d1 is logically greather than d2 in sort order
- if 0, then objects are equal
You can refer the javadoc for compare method
So when you are sorting dogs, and your compare method is comparing their ages, hence Tammy is less than Lacy according to the your method implementation.
Making Dog implement both Comparable
and Comparator
seems like a bad idea to me.
Collections.sort(list)
will causecompareTo()
method to be
invokedCollections.sort(list, new Dog())
will causecompare()
method to be invoked
I believe you should look into sorting user defined object using Comparable and Comparator
Error Message: The method sort(ListT) in the type Collections is not applicable for the arguments (ArrayListDate)
Because Collections.sort
expects java.lang.Comparable
and not your Comparable interface, change your Date
class to implement the java.lang.Comparable
.
public class Date implements java.lang.Comparable<Date>{
..
}
If you still want to define your own Comparable for some reasons and you still want to use Collections.sort then the your Comparable
has to be java.util.Comparable
interface Comparable<T> extends java.lang.Comparable<T> {
}
Collections.sort() declaration: why ? super T rather than T
Your proposed signature would probably work in Java-8. However in previous Java versions type inference was not so smart. Consider that you have List<java.sql.Date>
. Note that java.sql.Date
extends java.util.Date
which implements Comparable<java.util.Date>
. When you compile
List<java.sql.Date> list = new ArrayList<>();
Collections.sort(list);
It perfectly works in Java-7. Here T
is inferred to be java.sql.Date
which is actually Comparable<java.util.Date>
which is Comparable<? super java.sql.Date>
. However let's try your signature:
public static <T extends Comparable<T>> void sort(List<? extends T> list) {}
List<java.sql.Date> list = new ArrayList<>();
sort(list);
Here T
should be inferred as java.util.Date
. However Java 7 specification does not allow such inference. Hence this code can be compiled with Java-8, but fails when compiled under Java-7:
Main.java:14: error: method sort in class Main cannot be applied to given types;
sort(list);
^
required: List<? extends T>
found: List<Date>
reason: inferred type does not conform to declared bound(s)
inferred: Date
bound(s): Comparable<Date>
where T is a type-variable:
T extends Comparable<T> declared in method <T>sort(List<? extends T>)
1 error
Type inference was greatly improved in Java-8. Separate JLS chapter 18 is dedicated to it now, while in Java-7 the rules were much simpler.
Trying to solve The method sort(ListT, Comparator? super T) in the type Collections is not applicable for the arguments
The problem is that the list you're sorting has been declared as a list that can contain arbitrary objects. You can't apply a comparator of Patients to objects that might not be Patients.
To solve it, declare your list as a list of Patients:
List<Patient> list = new ArrayList<>(waitingList)
Error on Java Collection.sort
You're trying to sort a List<String>
with a Comparator<Students>
, which evidently cannot work. Perhaps you meant to use a List<Students>
instead? Or a Comparator<String>
?
Also, you have this:
@Override
public int compareTo(Students student) {
return this.compareTo(student);
}
which will simply call itself indefinitely. I'm not fully sure what you wanted to do there; perhaps sort by the last name as you do in StudentComparator
?
@Override
public int compareTo(Students student) {
return getLastname().compareTo(student.getLastname());
}
Unckecked method invocation warning on Collections.sort()
@Aominè had it right : MyType
implemented Comparable
instead of Comparable<MyType>
. The warning is gone now that I've changed this.
Related Topics
Passing a JavaScript Object Using Addjavascriptinterface() on Android
Access Resource Files in Android
Android: How to Disable List Items on List Creation
Does Glide Have a Method for Loading Both Png and Svg
Android Coding with Switch (String)
Issue When Using a Custom Font - "Native Typeface Cannot Be Made"
How to Delete a File on Google Drive Using Google Drive Android API
How One Interface Can Be Used for Different Background Android Tasks
Can't Get Download Url from Firebase Storge in Android
How to Skip Initial Data and Trigger Only New Updates in Firestore Firebase
Navigation View Items Will Not Respond When Pressed
Why Is Accessing Textview of a Fragment Inside Activity Throwing an Error
How to Set Up Intellij Idea for Android Applications
Android Studio Was Unable to Find a Valid Jvm (Related to MAC Os)
Android Recyclerview Scrolling Performance