Как я могу отсортировать список объектов Java на основе параметров, которые пользователь выбирает из выпадающего меню? - PullRequest
0 голосов
/ 10 декабря 2018

Я понимаю, как создать и использовать Comparator для списков объектов, основанных на нескольких атрибутах этих объектов.Тем не менее, я не уверен, как сделать это эффективно, предоставив пользователю выбор параметров для сортировки.Это GWT пользовательский интерфейс.

Например, у меня есть два раскрывающихся меню с 11 параметрами в каждом, соответствующими атрибутам объектов.Каждое меню также в виде кнопки для указания возрастающего / убывающего порядка.

Таким образом, пользователь может выбрать пример для сортировки по fileName, desc и timestamp, asc.Как я могу отсортировать эти объекты без смехотворно длинного оператора if для нескольких сотен возможных комбинаций?

Я мог бы сделать это, если бы сортировка была исправлена:

files.sort(Comparator.comparing(FileInfo::getFileName).thenComparing(FileInfo::getTimestamp).reversed());

(я мог бы получить там обратно asc / desc)
Но мне не нужно было печатать это длякаждый возможный вариант.Так как мне это сделать?

1 Ответ

0 голосов
/ 10 декабря 2018

Вы можете попробовать создать перечисление:

public enum FileInfoComparator {
    FILE_NAME(Comparator.comparing(FileInfo::getFileName)),
    TIMESTAMP(Comparator.comparing(FileInfo::getTimestamp)),
    SIZE(Comparator.comparing(FileInfo::getSize)),
    // ... add other criteria here
    ;

    private final Comparator<FileInfo> comparator;

    FileInfoComparator(Comparator<FileInfo> comparator) {
        this.comparator = comparator;
    }

    static Comparator<FileInfo> by(String key, boolean ascending) {
        Comparator<FileInfo> comparator = valueOf(key).comparator;
        return ascending ? comparator : comparator.reversed();
    }

    static Comparator<FileInfo> by(Pair<String, Boolean> criterion) {
        return by(criterion.getKey(), criterion.getValue());
    }

    static Optional<Comparator<FileInfo>> by(List<Pair<String, Boolean>> criteria) {
        return criteria.stream()
                .map(FileInfoComparator::by)
                .filter(Objects::nonNull)
                .reduce(Comparator::thenComparing);
    }

}

Затем используйте:

// Create the list of selected criteria based on user input:
// E.g. [FILE_NAME, false] will mean "sort by fileName descending"
List<Pair<String, Boolean>> selectedCriteria = ...

// Build your comparator and sort your list
FileInfoComparator.by(selectedCriteria).ifPresent(files::sort);

В случае выбора пустого пользователя files останется без изменений.

...