在平常開發工做中,常常須要優先處理集合中的某些對象,而優先處理的原則就是經過對象中的某個字段結合業務場景進行排序,這時候首先想到的就是在對象對應的表結構中添加排序字段,而這涉及到表結構的更改。在一個比較複雜的系統中,一個核心表結構的變化常常是須要涉及大量的代碼修改,而後進行迴歸測試,同時,若是該集合對象是經過外部系統接口調用的方式傳進來的話,咱們也並不能保證調用者給的集合必定是按照指定字段進行排序的,下面介紹一種不須要改變表結構,藉助枚舉進行集合自定義排序的方式。java
package com.imodule.finance.biz; /** * * @Description: 該枚舉類用來構造應收轉實收排序模型 * @author wenhaijin * @date 2018年4月18日 下午12:39:59 * */ public enum T5recvblItemEnum { LEVY_RECEIVABLE("L100", "LEVY應收",1), FISR_PRM("0100", "LEVY應收",2), RE_PRM("0200", "LEVY應收",3), EDR_LEVY_RECEIVABLE("L400", "保全LEVY應收",4), ADD_ADDITIONAL_PREMIUM("1000", "增長附加險補費",5), APL_REPAYMENT("7000", "APL還款",6); private String value; private String description; private int salt; private T5recvblItemEnum(String value, String description, int salt) { this.value = value; this.description = description; this.salt = salt; } public String value() { return value; } public String description() { return description; } public int salt() { return salt; } public static int saltOf(String value) { for (T5recvblItemEnum itemEnum : T5recvblItemEnum.values()) { if (itemEnum.value() == value) { return itemEnum.salt; } } return 100; } }
該枚舉對應三個屬性,排序字段值:value,描述:description,鹽值:salt,其中value字段就是集合對象中須要用來排序的字段,經過salt來進行排序sql
package com.imodule.finance.facade.impl.fincommon; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import com.imodule.finance.biz.T5recvblItemEnum; /** * @ClassName: CollectionSortTest * @Description: 集合對象排序測試類 * @author 溫海金 * @date 2018年7月19日 下午3:30:25 * */ public class CollectionSortTest { public static void main(String[] args) { List<RecvblBO> RecvblBOs = buildRecvblBOs(); /** * 對繳費途徑進行排序,這邊的排序默認按照jdk自己提供的字符順序進行排序 */ Collections.sort(RecvblBOs, new Comparator<RecvblBO>() { @Override public int compare(RecvblBO o1, RecvblBO o2) { return o1.getRecvway().compareTo(o2.getRecvway()); } }); /** * 按照Item-收付費科目進行排序,排序依據是枚舉中定義的權值 */ Collections.sort(RecvblBOs, new Comparator<RecvblBO>() { @Override public int compare(RecvblBO o1, RecvblBO o2) { return T5recvblItemEnum.saltOf(o1.getItem())-T5recvblItemEnum.saltOf(o2.getItem()); } }); RecvblBOs.forEach(entity ->{System.out.println(entity);}); } private static List<RecvblBO> buildRecvblBOs() { List<RecvblBO> RecvblBOs = new ArrayList<>(); RecvblBOs.add(new RecvblBO("0100","1")); RecvblBOs.add(new RecvblBO("2200","3")); RecvblBOs.add(new RecvblBO("9000","3")); RecvblBOs.add(new RecvblBO("7000","3")); RecvblBOs.add(new RecvblBO("L100","1")); RecvblBOs.add(new RecvblBO("0100","3")); RecvblBOs.add(new RecvblBO("1000","3")); RecvblBOs.add(new RecvblBO("7000","3")); RecvblBOs.add(new RecvblBO("L400","3")); RecvblBOs.add(new RecvblBO("L100","3")); RecvblBOs.add(new RecvblBO("0100","4")); RecvblBOs.add(new RecvblBO("0200","5")); return RecvblBOs; } } /** * @ClassName: RecvblBO * @Description: 構造一個應收對象用於排序測試 * @author 溫海金 * @date 2018年7月19日 下午3:33:57 * */ class RecvblBO{ /**收費科目**/ private String item; /**繳費方式**/ private String recvway; public RecvblBO() { super(); } public RecvblBO(String item, String recvway) { super(); this.item = item; this.recvway = recvway; } public String getItem() { return item; } public void setItem(String item) { this.item = item; } public String getRecvway() { return recvway; } public void setRecvway(String recvway) { this.recvway = recvway; } @Override public String toString() { return "RecvblBO [item=" + item + ", recvway=" + recvway + "]"; } }
以上代碼中構造了一個用於測試排序的對象,該對象就兩個屬性,收費科目item和繳費方式recvway,測試程序中先對繳費方式recvway進行排序,接着再對收費科目item進行排序,兩次排序後,打印出集合順序以下:數據庫
從排序結果能夠看出,第二次的排序並不會影響第一次排序效果,若要把收費科目爲9000的對象排到前面去,只須要調整枚舉對象中該科目的權值便可。ide
利用枚舉進行集合對象排序能夠靈活定義集合對象中根據某個屬性進行排序的規則,同時若須要根據多個字段排序,第二次的排序並不會影響第一次的排序結果。性能
利用這種方式進行排序的優勢是無需經過更改數據庫表結構增長排序字段,爲表結構新增一個排序字段是一個很是繁瑣的事情,特別是在一些規模稍大一點的公司,數據庫的變動須要提交工單讓數據庫管理員協助修改,而後在新增該表數據的地方也須要將該數據對應的排序字段置上,這一改動可能還會影響到已上線的一些功能。測試
這種排序方式的缺點是性能比較慢,由於你須要排序的集合已經從數據庫中load出來了,還須要重複遍歷該集合,若該集合中對象比較多或者須要對該集合對象根據兩個或更多的屬性進行排序,又會增長集合的遍歷次數,而這一過程是很是耗性能的。因此更好的作法應該是在進行表結構設計的的時候可以考慮得更加周全一些,爲須要排序的字段添加索引,若根據某字段排序的依據並不是按字母或數字的順序來定義,還須要預先爲該表新增一個字段並添加索引用於後續排序操做,直接在sql語句層面進行排序可以大幅度提升程序性能!ui