Построить соединение Comparator
постепенно , используя thenComparing(Comparator)
.
public static Comparator<Person> parseSortBy(String sortBy) {
Comparator<Person> sortComparator = null;
for (String field : sortBy.split(";")) {
Comparator<Person> c;
switch (field) {
case "firstname":
c = Comparator.comparing(Person::getFirstName);
break;
case "lastname":
c = Comparator.comparing(Person::getLastName);
break;
case "age":
c = Comparator.comparingInt(Person::getAge);
break;
case "country":
c = Comparator.comparing(Person::getCountry);
break;
default:
throw new IllegalArgumentException("Unknown sort spec: " + field);
}
sortComparator = (sortComparator == null ? c : sortComparator.thenComparing(c));
}
return sortComparator;
}
Хотя я бы на самом деле перевернул его бит, и пусть метод просто создаст Comparator
, оставив вызывающего его использовать.
Я бы также сделал общую часть метода повторно используемой.
public static Comparator<Person> parsePersonSortBy(String sortBy) {
return parseSortBy(sortBy, field -> {
switch (field) {
case "firstname": return Comparator.comparing(Person::getFirstName);
case "lastname": return Comparator.comparing(Person::getLastName);
case "age": return Comparator.comparingInt(Person::getAge);
case "country": return Comparator.comparing(Person::getCountry);
default: throw new IllegalArgumentException("Unknown sort spec: " + field);
}
});
}
// The following method should be in a separate helper class for reusability
public static <E> Comparator<E> parseSortBy(String sortBy, Function<String, Comparator<E>> fieldComparatorMapper) {
Comparator<E> sortComparator = null;
for (String field : sortBy.split(";")) {
Comparator<E> c = fieldComparatorMapper.apply(field);
sortComparator = (sortComparator == null ? c : sortComparator.thenComparing(c));
}
return sortComparator;
}
// You will now use it like this. No need for using a List
Arrays.sort(persons, parsePersonSortBy(sortByString));
Теперь вы можете легко улучшить синтаксический анализ для поддержки сортировки по убыванию , например, добавив знак -
минус после имени поля, так что "firstname-;age"
будет сортировать по firstname
по убыванию, а затем по age
по возрастанию.
public static <E> Comparator<E> parseSortBy(String sortBy, Function<String, Comparator<E>> fieldComparatorMapper) {
Comparator<E> sortComparator = null;
for (String field : sortBy.split(";")) {
boolean descending = field.endsWith("-");
Comparator<E> c = fieldComparatorMapper.apply(descending ? field.substring(0, field.length() - 1) : field);
if (descending)
c = c.reversed();
sortComparator = (sortComparator == null ? c : sortComparator.thenComparing(c));
}
return sortComparator;
}