使用JAVA自己的排序方法,有的时候是一个可行的选择。
先从简单的开始说起。
一、少数key的情况
有一个需求:根据 menu_level,sort排序,越小的越前面。
--
下面代码按照升序规则进行!
--
Collections.sort(menuList, new Comparator>() {
@Override
public int compare(Map o1, Map o2) {
// 进行判断
//compareTo当前面小于后面的时候,返回-1。也就是说如果要倒序,那么只要返回1即可。
int cpLevel=((Integer) o1.get("menu_level")).compareTo((Integer) o2.get("menu_level"));
Integer sort1=(o1.get("sort")==null)?10000:(Integer) o1.get("sort");
Integer sort2=(o2.get("sort")==null)?10000:(Integer) o2.get("sort");
int cpSort=sort1.compareTo(sort2);
if (cpLevel==1) {
return 1;
}
else if(cpLevel==0) {
return cpSort;
}
else {
return -1;
}
//return ;
}
});
---
现在稍微复杂下,后文是3个key的比较。
譬如有数据表books,它们的数据如下:select * from books order by author,price desc,publisher
2
102
生命在于运动
lml
1000.00
中华出版社
5
103
2020年异象
lml
90.00
福建出版社
9
108
以史鉴今
lml
90.00
西安出版社
4
104
奋斗在上海
lzf
1000.00
publzf
8
107
学习方法论
lzf
99.00
中天出版社
7
106
论自力更生的必要性
lzf
99.00
秦皇汉武
3
1498591124
Professional Java for Web Applications
Nicholas S. Williams
59.99
John Wiley & Sons
6
105
21世纪-中国-前进
五十
83.00
附件出版社
现在希望通过java排序, 代码如下:
@Overridepublic List>sortByNKeys() {
String sql= "select author,price,publisher,isbn,title from books";
List> bookList =jdbcTp.queryForList(sql);//使用java 8的 stream 功能进行排序//order by author,price desc,publisher
/*** 升序返回-1,倒序返回1即可 有多个key需要比较的时候(不考虑null或者""的情况),当第n个key返回的是0的时候继续比较,如果不是
* 则根据第n个key的比较值返回需要的结果。 譬如第1个key的比较结果是0,则比骄傲第2个, 假定第二的key的比较结果是-1
* 如果要根据第二个倒序,则返回1;如果要根据第二个升序,则直接发那会-1即可 以此类推*/Collections.sort(bookList,new Comparator>() {
@Overridepublic int compare(Map o1, Mapo2) {//进行判断
int cp1 = ((String) o1.get("author")).compareTo((String) o2
.get("author"));
BigDecimal price1= new BigDecimal(o1.get("price").toString());
BigDecimal price2= new BigDecimal(o1.get("price").toString());int cp2 =price1.compareTo(price2);
String p1= o1.get("publisher").toString();
String p2= o2.get("publisher").toString();int cp3 =p1.compareTo(p2);if (cp1 == 0) {if (cp2 == 0) {if (cp3 == 0) {return 0;
}else{returncp3;
}
}else{return cp2 * -1;
}
}else{returncp1;
}//return ;
}
});returnbookList;
}
结果输出如下:
[{"author": "Nicholas S. Williams","price": 59.99,"publisher": "John Wiley & Sons","isbn": "1498591124","title": "Professional Java for Web Applications"}, {"author": "lml","price": 1000.00,"publisher": "中华出版社","isbn": "102","title": "生命在于运动"}, {"author": "lml","price": 90.00,"publisher": "福建出版社","isbn": "103","title": "2020年异象"}, {"author": "lml","price": 90.00,"publisher": "西安出版社","isbn": "108","title": "以史鉴今"}, {"author": "lzf","price": 1000.00,"publisher": "publzf","isbn": "104","title": "奋斗在上海"}, {"author": "lzf","price": 99.00,"publisher": "中天出版社","isbn": "107","title": "学习方法论"}, {"author": "lzf","price": 99.00,"publisher": "秦皇汉武","isbn": "106","title": "论自力更生的必要性"}, {"author": "五十","price": 83.00,"publisher": "附件出版社","isbn": "105","title": "21世纪-中国-前进"}]
注:之所以,有所区别,是因为mysql比较的时候,默认不考虑大小写;而java字符串的CompareTo则是按照unicode编码比较进行的。
二、不定个数key的情况
以上可以应付一些简单的要求,如果有不断变化的,任意个数的key需要比较,那么怎么做?
可以参考的一个终极方案,代码如下:
public voidsort() {
String dataJson="[{\r\n" +
" \"author\": \"Nicholas S. Williams\",\r\n" +
" \"price\": 59.99,\r\n" +
" \"publisher\": \"John Wiley & Sons\",\r\n" +
" \"isbn\": \"1498591124\",\r\n" +
" \"title\": \"Professional Java for Web Applications\"\r\n" +
"}, {\r\n" +
" \"author\": \"lml\",\r\n" +
" \"price\": 1000.00,\r\n" +
" \"publisher\": \"中华出版社\",\r\n" +
" \"isbn\": \"102\",\r\n" +
" \"title\": \"生命在于运动\"\r\n" +
"}, {\r\n" +
" \"author\": \"lml\",\r\n" +
" \"price\": 90.00,\r\n" +
" \"publisher\": \"福建出版社\",\r\n" +
" \"isbn\": \"103\",\r\n" +
" \"title\": \"2020年异象\"\r\n" +
"}, {\r\n" +
" \"author\": \"lml\",\r\n" +
" \"price\": 90.00,\r\n" +
" \"publisher\": \"西安出版社\",\r\n" +
" \"isbn\": \"108\",\r\n" +
" \"title\": \"以史鉴今\"\r\n" +
"}, {\r\n" +
" \"author\": \"lzf\",\r\n" +
" \"price\": 1000.00,\r\n" +
" \"publisher\": \"publzf\",\r\n" +
" \"isbn\": \"104\",\r\n" +
" \"title\": \"奋斗在上海\"\r\n" +
"}, {\r\n" +
" \"author\": \"lzf\",\r\n" +
" \"price\": 99.00,\r\n" +
" \"publisher\": \"中天出版社\",\r\n" +
" \"isbn\": \"107\",\r\n" +
" \"title\": \"学习方法论\"\r\n" +
"}, {\r\n" +
" \"author\": \"lzf\",\r\n" +
" \"price\": 99.00,\r\n" +
" \"publisher\": \"秦皇汉武\",\r\n" +
" \"isbn\": \"106\",\r\n" +
" \"title\": \"论自力更生的必要性\"\r\n" +
"}, {\r\n" +
" \"author\": \"五十\",\r\n" +
" \"price\": 83.00,\r\n" +
" \"publisher\": \"附件出版社\",\r\n" +
" \"isbn\": \"105\",\r\n" +
" \"title\": \"21世纪-中国-前进\"\r\n" +
"}]";
List> dataList = JSON.parseObject(dataJson,new TypeReference>>(){});
System.out.println(dataList);
List> sortList=new ArrayList>();
Map a1=new HashMap();
a1.put("code", "publisher");
a1.put("sortPosition", 3);
a1.put("sortDirection", "desc");
sortList.add(a1);
Map a2=new HashMap();
a2.put("code", "author");
a2.put("sortPosition", 2);
a2.put("sortDirection", "asc");
sortList.add(a2);
Map a3=new HashMap();
a3.put("code", "price");
a3.put("sortPosition", 1);
a3.put("sortDirection", "desc");
sortList.add(a3);
Map a4=new HashMap();
a4.put("code", "title");
a4.put("sortPosition", 4);
a4.put("sortDirection", "asc");
sortList.add(a4);
Map a5=new HashMap();
a5.put("code", "isbn");
a5.put("sortPosition", 5);
a5.put("sortDirection", "asc");
sortList.add(a5);
Collections.sort(sortList,new Comparator>() {
@Overridepublic int compare(Map o1, Mapo2) {//进行判断
int cp1 = o1.get("sortPosition").toString().compareTo(o2.get("sortPosition").toString());returncp1;
}
});int sortSize=sortList.size();int[] compareResultArr=new int[sortSize];
int[] sortDirectionArr=new int[sortSize];
String[] colArr=new String[sortSize];for(int i=0;i
compareResultArr[i]=0;
sortDirectionArr[i]=sortList.get(i).get("sortDirection").equals("asc")?1:-1;
colArr[i]=sortList.get(i).get("code").toString();
}//排序的时候,必须保证多行在custom_id之后,而单行在custom_id之前,避免数据混乱
Collections.sort(dataList, new Comparator>() {
@Overridepublic int compare(Map o1, Mapo2) {//进行判断
for(int i=0,len=sortSize;i
Object v1=o1.get(colArr[i]);
Object v2=o2.get(colArr[i]);if (v1 instanceofString) {
compareResultArr[i]=v1.toString().compareTo(v2.toString());
}else{
compareResultArr[i]=new BigDecimal(v1.toString()).compareTo(newBigDecimal(v2.toString()));
}
}for(int i=0,len=sortSize;i
}
}//如果都是一样,则直接返回0
return 0;
}
});
System.out.println(dataList);
}
解决思路也比较简单:
1)使用数组保存每个key的比较值和排序方向值(升序1,降序-1)
2)对比较的结果循环判断,只要有不等于0(相等的)就返回
上面的解决还比较粗暴,可以稍微改进下:
Collections.sort(dataList, new Comparator>() {
@Overridepublic int compare(Map o1, Mapo2) {//进行判断
for(int i=0,len=sortSize;i
Object v1=o1.get(colArr[i]);
Object v2=o2.get(colArr[i]);if (v1 instanceofString) {
compareResultArr[i]=v1.toString().compareTo(v2.toString());
}else{
compareResultArr[i]=new BigDecimal(v1.toString()).compareTo(newBigDecimal(v2.toString()));
}
//只要有一个不相等,就可以返回了
if (compareResultArr[i]*sortDirectionArr[i]!=0){
return compareResultArr[i]*sortDirectionArr[i];
}
}//如果都是一样,则直接返回0
return 0;
}
});
注意:
1)以上方案没有考虑更多的类型,都是java的基本包装类
2) 不适合要求高性能的环境。如有需要,应该考虑购买算法,或者是使用其它算法计算
3)如果您的应用排序的数据大概是一万行内,且对时间要求不是特别高,那么可以使用以上方法。