Если я правильно понимаю, что вы хотите, вы хотите отсортировать список студентов по их высотам, затем их вес, а затем их возраст. Но вы хотите, чтобы этот список свойств был динамическим.
Это означает, что нам необходимо реализовать пользовательский Comparator
, который работает с данным свойством данного класса.
Первой реализацией может быть создание Map
, где каждое свойство String сопоставляется с ассоциированным Comparator
. Это был бы чистый подход (см. Комментарий @Manos Nikolaidis и комментарий Миши для этой реализации).
Истинное динамическое решение возможно с использованием немного отражения: сначала извлекается объявленное поле, имеющее заданное имя данного класса. Он доступен, поскольку это поле, скорее всего, личное. Наконец, возвращается значение Comparator
, сравнивающее значение этого поля для каждого ученика. Этот код предполагает слепо, что целевое свойство действительно Comparable
(в противном случае, почему мы хотели бы сравнить это поле?).
private static <U> Comparator<U> comparingProperty(String property, Class<U> clazz) {
try {
Field field = clazz.getDeclaredField(property);
field.setAccessible(true);
return Comparator.comparing(s -> {
try {
@SuppressWarnings("unchecked")
Comparable<Object> comparable = (Comparable<Object>) field.get(s);
return comparable;
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
});
} catch (NoSuchFieldException e) {
throw new AssertionError(e);
}
}
После этого у нас есть этот компаратор полезности, мы можем легко отсортировать список студентов. Поток свойств сортировки создается путем разбиения на ","
и обрезки результатов. Затем каждое свойство отображается на его соответствующий Comparator
и, наконец, этот поток уменьшается путем объединения всех компараторов вместе с Comparator::thenComparing
:
students.sort(Stream.of(sortOrder.split(","))
.map(String::trim)
.map(s -> comparingProperty(s, Student.class))
.reduce(Comparator::thenComparing)
.get()
);
«Таким образом, для приведенного выше примера, высота компаратора будет работать первый и возраст Последний.". Сортировка не работает. Вы сортируете по высоте. Когда высоты равны, вы сортируете по весу. Когда весы равны, вы сортируете по возрасту. –
Просьба пояснить: вам нужен один вид с тремя (или любыми цифрами) уровнями, как описано в @GilbertLeBlanc? Или три разных типа, выполненных в порядке, указанном в 'String'? –
@ ErickG.Hagstrom Я искал последний. –