Java对Map集合进行排序
实现 Comparator 接口,重写compare方法,完成自定义排序
int compare(Object o1, Object o2) 返回一个基本类型的整型
如果要按照升序排序,则o1 小于o2,返回-1(负数),相等返回0,01大于02返回1(正数)
如果要按照降序排序,则o1 小于o2,返回1(正数),相等返回0,01大于02返回-1(负数)
使用示例如下:
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class MapSort { public static void main(String[] args) { sortMap();//测试Map排序 } public static Map<String,Double> sortMap(){ Map<String,Double> map = new HashMap<String,Double>(); map.put("100M",(double) 100); map.put("10M",(double) 10); map.put("1000G",(double) 1000000); map.put("10G",(double) 10000); map.put("100T",(double) 100000000); map.put("10T",(double) 10000000); map.put("1T",(double) 1000000); //将map添加到list List<Map.Entry<String,Double>> list = new ArrayList<Map.Entry<String,Double>>(map.entrySet()); System.out.println("排序前:"+list); Collections.sort(list,new Comparator<Map.Entry<String,Double>>() { //从大到小 @Override public int compare(Entry<String, Double> o1, Entry<String, Double> o2) { if(o1.getValue()>o2.getValue()){ return -1; }else if(o1.getValue().equals(o2.getValue())){ String str1 = o1.getKey().substring(o1.getKey().length()-1, o1.getKey().length()); String str2 = o2.getKey().substring(o2.getKey().length()-1, o2.getKey().length()); //因为定义的是Double包装类型,在比较的时候需要用 equals才能判断相等,使用==比较的是对象的地址 if(str1.equals(str2)){ return 0; //数值相同时,比较的是单位,单位从大到小排序 T>G>M }else if((str1.equals("T") && str2.equals("G")) ||( str1.equals("T") && str2.equals("M") )||( str1.equals("G") && str2.equals("M"))){ return -1; }else{ return 1; } }else{ return 1; } } }); System.out.println("排序后(从大到小):"+list);
return map; } }
执行结果:
排序前:[1000G=1000000.0, 1T=1000000.0, 100T=1.0E8, 10T=1.0E7, 10G=10000.0, 100M=100.0, 10M=10.0]
排序后(从大到小):[100T=1.0E8, 10T=1.0E7, 1T=1000000.0, 1000G=1000000.0, 10G=10000.0, 100M=100.0, 10M=10.0]
实际应用
场景描述:100w+条数据插入数据库,需要分批插入(每次插入200000条数据为准)
/** * 返回数据分页结果信息(用于分批插入数据到数据库中-数据量过大时) * @param sumNumbers 总条数 * @return 分页结果list(seqid排序标识 从小到大,start 开始位置,end 插入条数) */ private List<Map<String,Integer>> getStartEndLimits(Integer sumNumbers){ if(sumNumbers <= 0 ){return null;}//如果为0 则返回null int len = sumNumbers/200000 +1; int modlen = sumNumbers%200000 ; int start = 0; int end = 200000; List<Map<String,Integer>> limitList = new ArrayList<Map<String,Integer>>(); //因数据量过大,需要分批插入(每200000条数据作为1批数据) len = sumNumbers/200000 +1; modlen = sumNumbers%200000 ; start = 0; end = 200000; if(sumNumbers < 200000){end=sumNumbers;} //如果总数量小于20w则不需要分批插入 for(int i=0;i<len;i++){ Map<String,Integer> limitMaps = new HashMap<String ,Integer>(); limitMaps.put("start",start); limitMaps.put("end",end); limitMaps.put("seqid", i); limitList.add(limitMaps); if(i==(len-2)){ end =modlen; } start +=200000; } // 从小到大排序 Collections.sort(limitList,new Comparator<Map<String,Integer>>(){ @Override public int compare(Map<String,Integer> map1, Map<String,Integer> map2) { if( map1.get("seqid") > map2.get("seqid")){ return 1; } return -1; } }); return limitList; }
调用示例:
private static Integer insertContactsOnelifetmp5(){ long starttime = System.currentTimeMillis(); //查询出数据量,再根据数据量分批插入数据库中 Integer tmp5nums = 1090023; // contactAgentMapper.getContactsOnelifetmp3nums();这里执行查询整体数据量的方法 System.out.println("查询数据量耗时:"+(System.currentTimeMillis()-starttime)/1000 +"s"); List<Map<String,Integer>> limitList = getStartEndLimits(tmp5nums); if(limitList != null){ for(Map<String,Integer> limitListObj : limitList){ System.out.println("limitListObj:"+limitListObj); // contactAgentMapper.insertContactsOnelifetmp3(limitListObj.get("start"),limitListObj.get("end")); 实际调用示例,这里获取开始下标及插入条数信息 执行插入 } } return tmp5nums; }
执行结果:
limitListObj:{start=0, end=200000, seqid=0} limitListObj:{start=200000, end=200000, seqid=1} limitListObj:{start=400000, end=200000, seqid=2} limitListObj:{start=600000, end=200000, seqid=3} limitListObj:{start=800000, end=200000, seqid=4} limitListObj:{start=1000000, end=90023, seqid=5}