Java8 對矩陣進行組合排序
阿新 • • 發佈:2018-11-30
首先,常規的實體類的多條件排序可參考:
Java8:Lambda表示式增強版Comparator和排序
我們有個Matrix 多條件排序要求,矩陣的列動態生成,程式可以知道該列是定性的還是定量的值。使用者在瀏覽這個Matrix 的時候,他會選擇若干個列,每個列的升降序和排序優先順序進行排序,後臺負責做真分頁排序。
比如一個matrix 的資料格式如下,java 使用的資料結構為:List<LinkedHashMap<String, Object>>,這樣可以動態儲存Matrix:
{"PERSON_ID":"11601","cataracta":"N","AGE":"50","GENDER":"N"},{"PERSON_ID":"10211","cataracta":"N","AGE":"51","GENDER":"Y"}
前端的排序請求體為:
{"analyseId":0,"cohortDefId":1960,"filters":[],"currentPage":1,"sort":{"AGE":"ASC","GENDER":"DESC"}}
主要是 sort 欄位,排在前面的 AGE 優先順序高於後面的 GENDER。明顯地,AGE 是定量的值,GENDER是定性的。
程式先要根據使用者選擇的排序列構造一個 comparator 的列表,資料的值型別決定了比較的方式(comparator 裡面的比較邏輯實現)。Comparator 的例項構造的方法有限,不得不先取一個 comparator 作為 nullsFirst 方法的引數例項化,然後就可以對剩餘的 comparator 序列化,最後總的排序例項傳給被排序的資料集進行排序。
LinkedList<Comparator<LinkedHashMap<String, Object>>> comparators = new LinkedList<>(); for (String varName : sortMap.keySet()){ if ("NUM".equals(varTypes.get(varName))){ // NUM 表示變數是定量的值,要轉化為 BigDecimal 後進行比較 try { comparators.add((Comparator<LinkedHashMap<String, Object>> & Serializable) ( LinkedHashMap<String, Object> o1, LinkedHashMap<String, Object> o2) -> new BigDecimal(String.valueOf(o1.get(varName))) .compareTo(new BigDecimal(String.valueOf(o2.get(varName))))); } catch (Exception e) { logger.error("當前變數在轉型時出錯,錯誤為::" + e.getMessage()); } } else { // 定性的轉化為 String 直接比較 comparators.add((Comparator<LinkedHashMap<String, Object>> & Serializable) ( LinkedHashMap<String, Object> o1, LinkedHashMap<String, Object> o2) -> String.valueOf(o1.get(varName)) .compareTo(String.valueOf(o2.get(varName)))); } } logger.info("完成排序驅動的例項化"); Comparator sortings = Comparator.nullsFirst(comparators.poll()); // 先要構造一個 comparator 例項 List<String> rest = new ArrayList<>(sortMap.values()); rest.remove(rest.get(0)); for (String asc : rest){ sortings = sortings.thenComparing("asc".equalsIgnoreCase(asc) ? comparators.poll() : comparators.poll().reversed()); } list.sort(sortings);