在平常开发工做中,常常须要优先处理集合中的某些对象,而优先处理的原则就是经过对象中的某个字段结合业务场景进行排序,这时候首先想到的就是在对象对应的表结构中添加排序字段,而这涉及到表结构的更改。在一个比较复杂的系统中,一个核心表结构的变化常常是须要涉及大量的代码修改,而后进行回归测试,同时,若是该集合对象是经过外部系统接口调用的方式传进来的话,咱们也并不能保证调用者给的集合必定是按照指定字段进行排序的,下面介绍一种不须要改变表结构,借助枚举进行集合自定义排序的方式。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