代码之家  ›  专栏  ›  技术社区  ›  mal

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

  •  3
  • mal  · 技术社区  · 6 年前

    我知道如何建造和使用 Comparator 用于基于这些对象的多个属性的对象列表。但是,我不确定如何通过让用户选择要排序的参数来高效地执行此操作。这是一个 GWT 用户界面。

    例如,我有两个下拉菜单,每个菜单有11个参数,对应于对象的属性。每个菜单也作为旁边的按钮指定升序/降序。

    因此,用户可以选择示例,按 fileName, desc timestamp, asc . 我怎么能把这些东西分类,而不花一个可笑的长 if 对几百种可能的组合的陈述?

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

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

    (我可能在后面找到asc/desc)
    但我不应该为每个可能的选择都打出来。那我该怎么做呢?

    1 回复  |  直到 6 年前
        1
  •  1
  •   ETO    6 年前

    可以尝试创建枚举:

    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 将保持原样。