Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Using Comparators in combination with custom Comparators

I want to sort the following example list which currently contains only Strings with my own custom rules.

ArrayList<String> coll = new ArrayList<>();
coll.add("just");
coll.add("sdsd");
coll.add("asb");
coll.add("b as");
coll.add("just");
coll.add("dhfga");
coll.add("jusht");
coll.add("ktsa");
coll.add("just");
coll.add("just");

I know that I could write my own comparator for this, but as I know that Java also got comparators which solve this problem partially I want to know how I can use the ones from the Java API in combination with my own one.


How should it be sorted?

The word just should always be the first word to appear in the list followed by all other words in alphabetical order.

Comparator.naturalOrder() sorts the list in alphabetical order, but how can I combine this comperator with a custom one which checks whether the word is just or something else.

like image 423
ShadowDragon Avatar asked May 21 '18 18:05

ShadowDragon


People also ask

What is custom Comparator in Java?

Custom Comparator are used to compare the objects of user-defined classes. Syntax: bool comp(object o1, object o2) { // There can be any condition implemented as per the need of the problem statement.

Which is better Comparator or comparable in Java?

Comparable vs Comparator. Comparable interface can be used to provide single way of sorting whereas Comparator interface is used to provide different ways of sorting. For using Comparable, Class needs to implement it whereas for using Comparator we don't need to make any change in the class.

What are the two interfaces that you can implement to your class if you want your objects instance of that class to be sorted?

String and Date both implement the Comparable interface. Comparable implementations provide a natural ordering for a class, which allows objects of that class to be sorted automatically.


2 Answers

You can do this something like that:

coll.sort(Comparator
    .comparingInt((String s) -> s.equals("just") ? 0 : 1) // Words "just" first
    .thenComparing(Comparator.naturalOrder())); // Then others
like image 119
ZhekaKozlov Avatar answered Sep 21 '22 23:09

ZhekaKozlov


You could integrate the criteria into the comparator like

coll.sort(Comparator.comparing((String s) -> !s.equals("just"))
                    .thenComparing(Comparator.naturalOrder()));

or you separate the operations, first moving all occurrences of "just" to the front, then sorting the remaining elements only:

int howManyJust = 0;
for(int ix = 0, num = coll.size(); ix < num; ix++)
    if(coll.get(ix).equals("just") && ++howManyJust <= ix)
        Collections.swap(coll, ix, howManyJust-1);

coll.subList(howManyJust, coll.size()).sort(Comparator.naturalOrder());

while this may look more complicated, it is potentially more efficient, especially for larger lists.

like image 35
Holger Avatar answered Sep 20 '22 23:09

Holger