# 潮流偉泓 ### 針對Map如何排序的問題 Map本身透過k v方式進行裝填資料,唯一要有順序的只能透過LinkedHashMap 依照資料填入的順序排序,但要針對裡面的value進行排序要進行以下變換 * 共用排序: 升序、降序 先設定排序的方法 domain要先 降序 Comparator<Map.Entry> sortByValue = (e1, e2) -> { return ((Integer) e2.getValue()).compareTo((Integer) e1.getValue()); }; 升序 Comparator<Map.Entry> sortDownByValue = (e1, e2) -> { return ((Integer) e1.getValue()).compareTo((Integer) e2.getValue()); }; * map轉成list,對裝到list裡面的map值依據Comparator定義做排序因為無法針對Map進行排序,因此要先轉成List Map.Entry等同KeyValue的意思 List<Map.Entry> systemBigList = new ArrayList<>(systemMap.entrySet()); List<Map.Entry> systemSmallList = new ArrayList<>(systemMap.entrySet()); * 開始進行排序 Collections.sort(systemBigList, sortByValue); Collections.sort(systemSmallList, sortDownByValue); * Sdg206ColumnDTO implements Comparator<ObjUseCntDTO> 可以針對 domain進行實作Comparator ,以override methods 如下: @Override public int compare(ObjUseCntDTO o1, ObjUseCntDTO o2) { return 0; } * 操作小技巧 把List的東西撈出來裝在LinkedHashMap LinkedHashMap<String, Object> systemMap = new LinkedHashMap<>(); for (ObjUseCntDTO dto : systemList) { if (systemMap.get(dto.getObj_nm()) != null) { //假設有存在的名字 int usage_cnt = (Integer) systemMap.get(dto.getObj_nm()); systemMap.put(dto.getObj_nm(), dto.getUsage_cnt() + usage_cnt); } else { systemMap.put(dto.getObj_nm(), dto.getUsage_cnt()); } } * 針對List撈出來就做map的Key判斷,如果key不存在,就新增key 並新增0 這是針對塞0的部分 for (MetaTbl tbl : dataListDTO) { if (!dataListMap.containsKey(tbl.getTblNm())) { dataListMap.put(tbl.getTblNm(), 0); } } * 拿出當下拿到的key的value 原先可能是Map<String,Object> XXX Object裡面就是另一個Map 因此透過以下方式 get該key拿到value是Map 再用Map接值拿到value的Map, Map<String, Object> dtoMap = (Map<String, Object>) map.get(dto.getDataDate()); dtoMap.put(dto.getExecDate(), dto.getSumDataCnt()); * map塞零其他技巧 //思考:應該在這邊做一個迴圈 去判斷裡面有沒有 //先用陣列把最統計日撈出來放進去 String lastExecDate = null; String preExecDate = null; List<String> combineExec = new ArrayList<>(); List<String> testExec = new ArrayList<>(); if (pretVol.size() != 0) { preExecDate = pretVol.get(0).getExecDate(); //放在迴圈裏面 這樣才不會有null佔據index combineExec.add(preExecDate); testExec.add(preExecDate); } lastExecDate = lastVol.get(0).getExecDate(); //如果只有最新資料 那陣列只會有lastExecDate combineExec.add(lastExecDate); testExec.add(lastExecDate); //反轉陣列裡面內容 讓最新一期在index 0 前一期在index 1 Collections.reverse(testExec); //利用原本整理好的鄭烈 塞入key後尋找對應的value for (String mapKey : map.keySet()) { Map<String, Object> mapValue = (Map<String, Object>) map.get(mapKey); //如果value 長度小於二 因為裡面照理來說只有兩筆統計日的資料 if (mapValue.size() < 2) { //找出value裡面的map的key值 for (String mapValueKey : mapValue.keySet()) { //如果陣列裡面的字串 key沒有 if (combineExec.contains(mapValueKey)) { //移除陣列裡面重複的字串 boolean bool = combineExec.remove(mapValueKey); } } //把陣列裡面剩下的字串取出來塞進同一個map key裡面的物件 的value //原本combineExec只會有兩筆資料 刪掉重複地之後就剩下最需要的一筆 //只針對size<2部分做新增 //而且如果陣列大於等於1 又小於2 因為怕剛好只有一筆資料 然後又刪除 因為有可能沒有前期資料 刪除後其實就沒有資料了 //combineExec指前後期結合後的統計日 最後為0代表不用再新增一筆為0的資料 if (combineExec.size() >= 1) { mapValue.put(combineExec.get(0), 0); } } } * 針對最新一期及前一前的整理,找出相同的字串包再分別的List,傳到前端 // test 歸零問題 ************************************************************************************** List<Integer> lastListNum = new ArrayList<>(); List<Integer> preListNum = new ArrayList<>(); for (String mapKey : map.keySet()) { //先取出value 一樣是Map Map<String, Object> mapValue = (Map<String, Object>) map.get(mapKey); for (String mapKey2 : mapValue.keySet()) { //假設key等於前一期 裝進前一期的list if (testExec.get(0).equals(mapKey2)) { Integer mapValue3 = (Integer) mapValue.get(mapKey2); lastListNum.add(mapValue3); //假設key等於最新一期 裝進最新一期的list } else if (testExec.get(1).equals(mapKey2)) { Integer mapValue3 = (Integer) mapValue.get(mapKey2); preListNum.add(mapValue3); } } } dataVolMap.put("LastListNum", lastListNum); dataVolMap.put("PreListNum", preListNum);