亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在java中使用帶條件的比較器

如何在java中使用帶條件的比較器

飲歌長嘯 2023-04-19 16:35:15
我正在嘗試根據從 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 一樣將它們鏈接在一起
查看完整描述

2 回答

?
互換的青春

TA貢獻1797條經驗 獲得超6個贊

假設這sortlist是一個列表SortCriteria,它是這樣的一個類:


class SortCritera {

    private String key;

    private String order;


    public String getKey() {

        return key;

    }


    public String getOrder() {

        return order;

    }


    // 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")) {

    comparator = comparator.reversed();

}

for(int i = 1 ; i < sortlist.size() ; i++) {

    if (sortlist.get(i).getOrder().equals("DESC")) {

        comparator = comparator.thenComparing(comparators.get(sortlist.get(i).getKey()).reversed());

    } else {

        comparator = comparator.thenComparing(comparators.get(sortlist.get(i).getKey()));

    }

}

// now you can sort with "comparator".

正如 Holger 所建議的那樣,您也可以使用 Stream API 來執行此操作:


sortlist.stream().map(sc -> {

    Comparator<Employee> c = comparators.get(sc.getKey()); 

    return sc.getOrder().equals("DESC")? c.reversed(): c; 

}).reduce(Comparator::thenComparing)

.ifPresent(x -> Collections.sort(originalList, x));


查看完整回答
反對 回復 2023-04-19
?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

您可以創建一個方法,當傳遞排序鍵時,您可以提供適當的比較器:


public Comparator<Employee> getComparator(String sortKey) {

    if("name".equals(sortKey)) {

        return Comparator.comparing(Employee::getName);

    } else if ("place".equals(sortKey) {

        return Comparator.comparing(Employee::getPlace);

    } else {

        throw new IllegalArgumentException();

    }

}

要稱它為:


Collections.sort(sourceList, getComparator(sortKey).reversed()

                .thenComparing(Employee::getCount));

雖然您也可以自己編寫,但我發現最好委托“標準”部分并簡單地編寫與此不同的部分。


如果您發現自己有很多這樣的排序鍵,那么更合適的方法是使用映射:


private static final Map<String, Comparator<Employee>> COMPARE_MAP = new HashMap<>() {{

    put.("name", Comparator.comparing(Employee::getName));

    put.("place", Comparator.comparing(Employee::getPlace));

}});


public Comparator<Employee> getComparator(String sortKey) {

    if(COMPARE_MAP.containsKey(sortKey)) {

        return COMPARE_MAP.get(sortKey);

    } else {

        throw new IllegalArgumentException();

    }

}

反射也是一種選擇,但我會謹慎使用反射,除非不這樣做變得不切實際。在這種情況下,您可以創建自己的注釋來確定類 Employee 的哪些字段可用于排序。


查看完整回答
反對 回復 2023-04-19
  • 2 回答
  • 0 關注
  • 164 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號