Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 - customised sort based on specific order

I would like to sort the user list based on their status but the order must be based on the order that I set.

I want to set the order of list,

The order should be 1, 0 , 5. We should also keep in mind to order the username as well.

List<User> users = new ArrayList();
         users.add(new User("A", 1));
         users.add(new User("B", 5));
         users.add(new User("C", 0));
         users.add(new User("D", 1));
         users.add(new User("E", 5));
         users.add(new User("F", 0));

Here's the user class

public class User {
         private String username;
         private Integer status;
     }

It should look like this

[
    {
      "username": "A",
      "status": 1
    },
    {
       "username": "D",
       "status": 1
    },
    {
       "username": "C",
       "status": 0
    },
    {
       "username": "F",
       "status": 0
    },
    {
       "username": "B",
       "status": 5
    },
    {
       "username": "E",
       "status": 5
    }
]

I not sure if it's possible to use Comparator.comparing, since this one is neither ascending nor descending order.

like image 493
KennethC Avatar asked Nov 12 '18 03:11

KennethC


Video Answer


1 Answers

One approach could be to hold a list with the order you want and sort the users according to its index:

final List<Integer> order = Arrays.asList(1, 0, 5);
users.sort(
    Comparator.comparing((User u) -> order.indexOf(u.getStatus()))
              .thenComparing(User::getUsername));

Note that while this approach should be reasonable for a small number of statuses (like you currently have), it may slow down sorting if there are a large number of statuses and you need to do perform an O(n) search each time. A better performing approach (albeit arguably not as sleek), would be to use a map:

final Map<Integer, Integer> order = new HashMap<>();
order.put(1, 0);
order.put(0, 1);
order.put(5 ,2);
users.sort(Comparator.comparing((User u) -> order.get(u.getStatus()))
                     .thenComparing(User::getUsername));
like image 128
Mureinik Avatar answered Oct 18 '22 08:10

Mureinik