qwerty98
qwerty98

Reputation: 29

Dynamic order by with java with list

I want to sort my list(taken from the db I can't sort using query), but I don't know for what parameters, the parameters are chosen by the user. The following code sorts by first and last name in desc, but how do I create a dynamic one? I have made many attempts, but I have failed.

myList.sort(Comparator.comparing(DTO::getName)
         .thenComparing(DTO::getLastName).reversed());

Upvotes: 1

Views: 451

Answers (1)

Mustapha Belmokhtar
Mustapha Belmokhtar

Reputation: 1219

To create a customized order depending on the user params, I suggest something like :

1- Create an enumeration of the possible sorting orders which will be populated by the parameters in the user query, say that, for example, I have 3 orders BY_ID, BY_NAME, BY_LAST_NAME.

2- Then create a list of this enumeration;

3- After that create a map, where the key is the enumeration above, and the value is a comparator.

4- populate the map.

5-Derive a reduced final comparator from both the list of orders you had in (2), and the map in (3).

6- Sort your list by that final comparator.

Putting all the steps together

  • The enumeration of the sort orders :
public enum SortOrder {
    BY_ID,
    BY_NAME,
    BY_LAST_NAME;
}
  • The main test method :
public static void main(String[] args) {
         /**dummy objects for test purposes**/

            DTO firstDTO = new DTO();
            firstDTO.setId(1);
            firstDTO.setName("John");
            firstDTO.setLastName("Doe");

            DTO secondDTO = new DTO();
            secondDTO.setId(2);
            secondDTO.setName("John");
            secondDTO.setLastName("Doe");

            DTO thirdDTO = new DTO();
            thirdDTO.setId(2); // the id is repeated
            thirdDTO.setName("Alice");
            thirdDTO.setLastName("Bob");

            final List<SortOrder> sortOrders = createSortOrdersFromInputParams(/*the params passed as args*/);
            final List<DTO> myList = Arrays.asList(firstDTO, secondDTO, thirdDTO); // your list that is supposed to come from a DB
            final Map<SortOrder, Comparator<DTO>> map = new EnumMap<>(SortOrder.class);

            final Comparator<DTO> defaultComparator = Comparator.nullsLast(Comparator.comparing(DTO::getId)); // you'all always need a default comparator , say by ID

            map.put(SortOrder.BY_ID, defaultComparator);
            map.put(SortOrder.BY_NAME, Comparator.nullsLast(Comparator.comparing(DTO::getName)));
            map.put(SortOrder.BY_LAST_NAME, Comparator.nullsLast(Comparator.comparing(DTO::getLastName)));

            final Comparator<DTO> finalComparator = sortOrders.stream()
                    .map(map::get)
                    .filter(Objects::nonNull)
                    .reduce(Comparator::thenComparing)
                    .orElse(defaultComparator);

            myList.sort(finalComparator);
            System.out.println(myList);

        }
  • The method that turns parameters of the user input into sort orders
    private static List<SortOrder> createSortOrdersFromInputParams(/*params passed as args*/) {
        return Arrays.asList(SortOrder.BY_ID, SortOrder.BY_NAME, SortOrder.BY_LAST_NAME);
    }

I hope this will respond to your case.

Upvotes: 2

Related Questions