猿问

如何在java中使用带条件的比较器

我正在尝试根据从 API 收到的排序键和排序顺序对列表进行排序。例如,我有一个带有 sortkey 和 sortorder 的列表,我需要根据它进行排序。


List<SortList> sortlist;

我有一个对象列表:


List<Employee> employee;

我可以使用排序


Collections.sort(sourceList, Comparator

                .comparing(Employee::getAge).reversed()

                .thenComparing(Employee::getCount));

但是我需要在一个条件下检查 sortfeild,并基于该条件只考虑对字段进行排序。


前任:


if(sortkey = "name") sortbythatkey from sortlist 按排序顺序


if (sortkey = "place") sortbythat key from sortlist 按排序顺序


所以在这里,如果排序列表同时具有名称和位置,那么它应该同时按键和顺序排序


知道我怎么能做到这一点?


排序列表包含:


{

    "sortKey":"name",

    "sortOrder":"ASC"


},

{

    "sortKey":"place",

    "sortOrder":"DESC"


}

要求是像 SQL 中的 ORDER BY 一样将它们链接在一起


饮歌长啸
浏览 123回答 2
2回答

互换的青春

假设这sortlist是一个列表SortCriteria,它是这样的一个类:class SortCritera {&nbsp; &nbsp; private String key;&nbsp; &nbsp; private String order;&nbsp; &nbsp; public String getKey() {&nbsp; &nbsp; &nbsp; &nbsp; return key;&nbsp; &nbsp; }&nbsp; &nbsp; public String getOrder() {&nbsp; &nbsp; &nbsp; &nbsp; return order;&nbsp; &nbsp; }&nbsp; &nbsp; // constructors, setters...}您首先需要一个HashMap<String, Comparator<Employee>>为每个可能的键存储所有相应的比较器:HashMap<String, Comparator<Employee>> comparators = new HashMap<>();comparators.put("name", Comparator.comparing(Employee::getName));comparators.put("age", Comparator.comparing(Employee::getAge));// ...然后你可以循环sortlist并继续调用thenComparing:Comparator<Employee> comparator = comparators.get(sortlist.get(0).getKey());if (sortlist.get(0).getOrder().equals("DESC")) {&nbsp; &nbsp; comparator = comparator.reversed();}for(int i = 1 ; i < sortlist.size() ; i++) {&nbsp; &nbsp; if (sortlist.get(i).getOrder().equals("DESC")) {&nbsp; &nbsp; &nbsp; &nbsp; comparator = comparator.thenComparing(comparators.get(sortlist.get(i).getKey()).reversed());&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; comparator = comparator.thenComparing(comparators.get(sortlist.get(i).getKey()));&nbsp; &nbsp; }}// now you can sort with "comparator".正如 Holger 所建议的那样,您也可以使用 Stream API 来执行此操作:sortlist.stream().map(sc -> {&nbsp; &nbsp; Comparator<Employee> c = comparators.get(sc.getKey());&nbsp;&nbsp; &nbsp; return sc.getOrder().equals("DESC")? c.reversed(): c;&nbsp;}).reduce(Comparator::thenComparing).ifPresent(x -> Collections.sort(originalList, x));

大话西游666

您可以创建一个方法,当传递排序键时,您可以提供适当的比较器:public Comparator<Employee> getComparator(String sortKey) {&nbsp; &nbsp; if("name".equals(sortKey)) {&nbsp; &nbsp; &nbsp; &nbsp; return Comparator.comparing(Employee::getName);&nbsp; &nbsp; } else if ("place".equals(sortKey) {&nbsp; &nbsp; &nbsp; &nbsp; return Comparator.comparing(Employee::getPlace);&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException();&nbsp; &nbsp; }}要称它为:Collections.sort(sourceList, getComparator(sortKey).reversed()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .thenComparing(Employee::getCount));虽然您也可以自己编写,但我发现最好委托“标准”部分并简单地编写与此不同的部分。如果您发现自己有很多这样的排序键,那么更合适的方法是使用映射:private static final Map<String, Comparator<Employee>> COMPARE_MAP = new HashMap<>() {{&nbsp; &nbsp; put.("name", Comparator.comparing(Employee::getName));&nbsp; &nbsp; put.("place", Comparator.comparing(Employee::getPlace));}});public Comparator<Employee> getComparator(String sortKey) {&nbsp; &nbsp; if(COMPARE_MAP.containsKey(sortKey)) {&nbsp; &nbsp; &nbsp; &nbsp; return COMPARE_MAP.get(sortKey);&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException();&nbsp; &nbsp; }}反射也是一种选择,但我会谨慎使用反射,除非不这样做变得不切实际。在这种情况下,您可以创建自己的注释来确定类 Employee 的哪些字段可用于排序。
随时随地看视频慕课网APP

相关分类

Java
我要回答