如何根据用户从下拉菜单中选择的参数对 Java 个对象列表进行排序?

How can I sort a list of Java objects based on parameters that a user selects from a drop down menu?

我了解如何根据对象的多个属性构建和使用 Comparator 对象列表。但是,我不确定如何通过让用户选择要排序的参数来有效地做到这一点。这是一个GWTUI。

比如我有两个下拉菜单,每个有11个参数,对应对象的属性。每个菜单也作为旁边的一个按钮来指定ascending/descending顺序。

因此,用户可以选择按 fileName, desctimestamp, asc 排序。我怎样才能对这些对象进行排序,而不用长得离谱的 if 语句来表示几百种可能的组合?

如果排序是固定的,我可以这样做:

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

(我可能把 asc/desc 倒过来了)
但我不应该为每个可能的选项都输入它。那我该怎么做呢?

您可以尝试创建一个枚举:

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 将保持不变。