Sorting using Comparator- Descending order (User defined classes)
You can do the descending sort of a user-defined class this way overriding the compare() method,
Collections.sort(unsortedList,new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return b.getName().compareTo(a.getName());
}
});
Or by using Collection.reverse()
to sort descending as user Prince mentioned in his comment.
And you can do the ascending sort like this,
Collections.sort(unsortedList,new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
});
Replace the above code with a Lambda expression(Java 8 onwards) we get concise:
Collections.sort(personList, (Person a, Person b) -> b.getName().compareTo(a.getName()));
As of Java 8, List has sort() method which takes Comparator as parameter(more concise) :
personList.sort((a,b)->b.getName().compareTo(a.getName()));
Here a
and b
are inferred as Person type by lambda expression.
Creating a comparator to pass to .sort() in java not suitable method error
Collections.sort
accepts a Comparator<T>
as the second argument, you are giving it a Comparable<T>
. This is why the error pops up.
Even if Collections.sort
did accept a Comparable<T>
, your implementation violates the general contract of Comparable
.
You seem to just want to sort the strings in reverse order. You can just do something like this:
Collections.sort(directories, Comparator.reverseOrder());
If I misunderstood you and you actually want to sort it in some custom way, you can do something like this:
Collections.sort(directories, Comparator.comparing(s -> /*map the string to something you want to compare*/));
Java: Sort a list of Objects using Comparator with second word of the property
In Java 8 Streams mode:
Comparator<? super Animal> animalComparator = (a, b) -> {
StringTokenizer firstTokenizer = new StringTokenizer(a.getName(), " ");
firstTokenizer.nextToken();
StringTokenizer secondTokenizer = new StringTokenizer(b.getName(), " ");
secondTokenizer.nextToken();
return firstTokenizer.nextToken().compareTo(secondTokenizer.nextToken());
};
myList = myList.stream().sorted(animalComparator).collect(Collectors.toList());
How to perform sorting based on Comparator keeping original sort intact in Java
This is not because your Employee
class already has a default ordering, that using Collections.sort
with a custom comparator will introduce a new layer of ordering.
For example let's say that the default ordering of your Employees
is by their salary in ascending order. Now let's say you want to sort them by salary in descending order.
According to your logic how this will behave?
Collections.sort(employees, new SalaryDescendingComparator());
The fact is that when you provide a custom comparator to Collections.sort
, it will use only this one and not the sorting mechanism that you implemented in your Employee
class.
As the doc states:
Sorts the specified list according to the order induced by the
specified comparator.
So because the SalaryComparator
compares employees only by their salary, that's why you get this output.
If you want to sort by name first and then by salary, you'll have to do this in one time, i.e :
public class Employee implements Comparable<Employee> {
private int empSalary;
private String empName;
@Override
public int compareTo(Employee e) {
int cmp = this.empName.compareTo(e.empName);
return cmp != 0 ? cmp : Integer.compare(empSalary, e.empSalary);
}
}
How to use Comparator with conditions in java
Assuming that sortlist
is a list of SortCriteria
, which is a class like this:
class SortCritera {
private String key;
private String order;
public String getKey() {
return key;
}
public String getOrder() {
return order;
}
// constructors, setters...
}
You first need a HashMap<String, Comparator<Employee>>
to store all the corresponding comparators for each possible key:
HashMap<String, Comparator<Employee>> comparators = new HashMap<>();
comparators.put("name", Comparator.comparing(Employee::getName));
comparators.put("age", Comparator.comparing(Employee::getAge));
// ...
Then you can loop through the sortlist
and keep calling thenComparing
:
Comparator<Employee> comparator = comparators.get(sortlist.get(0).getKey());
if (sortlist.get(0).getOrder().equals("DESC")) {
comparator = comparator.reversed();
}
for(int i = 1 ; i < sortlist.size() ; i++) {
if (sortlist.get(i).getOrder().equals("DESC")) {
comparator = comparator.thenComparing(comparators.get(sortlist.get(i).getKey()).reversed());
} else {
comparator = comparator.thenComparing(comparators.get(sortlist.get(i).getKey()));
}
}
// now you can sort with "comparator".
As Holger has suggested, you can use the Stream API to do this as well:
sortlist.stream().map(sc -> {
Comparator<Employee> c = comparators.get(sc.getKey());
return sc.getOrder().equals("DESC")? c.reversed(): c;
}).reduce(Comparator::thenComparing)
.ifPresent(x -> Collections.sort(originalList, x));
How to use a separate comparator class to sort an array list
I would use
Collections.sort(list, RationalComparator.INSTANCE);
where the comparator looks like
enum RationalComparator implements Comparator<Rational> {
INSTANCE;
public int compare(Rational a, Rational b) {
// do your comparison here
}
}
Array Sorting Using A Comparator in Java
I just put together this simple example to show two different ways of using a Comparator
:
import java.util.Arrays;
import java.util.Comparator;
public class ArraySort
{
public static void main(String[] args)
{
String[][] data = new String[][]
{
new String[] { "Casablanca", "Warner Brothers", "1942" },
new String[] { "Citizen Kane", "RKO Pictures", "1941" },
new String[] { "Singin' in the Rain", "MGM", "1952" },
new String[] { "The Wizard of OZ", "MGM", "1930"},
new String[] { "AaaaaThe Wizard of OZ", "MGM", "1943"}
};
Arrays.sort(data, new Comparator<String[]>() {
@Override
public int compare(final String[] entry1, final String[] entry2) {
final String field1 = entry1[0];
final String field2 = entry2[0];
return field1.compareTo(field2);
}
});
print(data);
System.out.println();
Arrays.sort(data, new SortByDate());
print(data);
System.out.println();
Arrays.sort(data, new SortByCompany());
print(data);
}
public static void print(String[][] data){
for (String[] array : data){
for (String s : array){
System.out.print(s + " ");
}
System.out.println();
}
}
}
public class SortByDate implements Comparator<String[]>{
@Override
public int compare(final String[] entry1, final String[] entry2) {
final String field1 = entry1[2];
final String field2 = entry2[2];
return field1.compareTo(field2);
}
}
public class SortByCompany implements Comparator<String[]>{
@Override
public int compare(final String[] entry1, final String[] entry2) {
final String field1 = entry1[1];
final String field2 = entry2[1];
return field1.compareTo(field2);
}
}
Output:
AaaaaThe Wizard of OZ MGM 1943
Casablanca Warner Brothers 1942
Citizen Kane RKO Pictures 1941
Singin' in the Rain MGM 1952
The Wizard of OZ MGM 1930
The Wizard of OZ MGM 1930
Citizen Kane RKO Pictures 1941
Casablanca Warner Brothers 1942
AaaaaThe Wizard of OZ MGM 1943
Singin' in the Rain MGM 1952
The Wizard of OZ MGM 1930
AaaaaThe Wizard of OZ MGM 1943
Singin' in the Rain MGM 1952
Citizen Kane RKO Pictures 1941
Casablanca Warner Brothers 1942
Related Topics
Intellij Can't Recognize Javafx 11 With Openjdk 11
How to "Decompile" Java Class Files
Initialization of an Arraylist in One Line
How to Capitalize the First Character of Each Word in a String
Fastest Way to Determine If an Integer'S Square Root Is an Integer
How to Add Blank Page in Digitally Signed Pdf Using Java
Difference Between Jdk and Jre
How to Check If a String Contains Another String in a Case Insensitive Manner in Java
Placing Component on Glass Pane
When to Choose Checked and Unchecked Exceptions
How to Access Java-Classes in the Default-Package
Difference Between a Static and a Non-Static Initialization Code Block
What Are the Effects of Exceptions on Performance in Java
Best Implementation For Hashcode Method For a Collection
How Does the "Final" Keyword in Java Work (I Can Still Modify an Object.)