现在要展示一批公司名单,原本是根据添加的前后顺序进行排列。
但是部分公司支付广告费,意将其排名靠前。
公司名单如下:
1 化为
2 藤训
3 柏杜
4 阿李
5 孜洁
简洁说一下排序规则,大部分语言的排序都是根据权重大小进行排序的。像数字、单字符权重就是它的值;对于字符串,大部分排序都是以首字母的权重来确定,首字母相同则对比第二个……。
要实现自定义规则的话,那么我们只需修改权重值的生成规则即可。MySQL、Java中也提供了一些方法来修改。
MySQL FIELD:
MySQL FIELD的权重值是根据FIELD()中值匹配的下标来进行判断的。比如FIELD(
name,"藤训","柏杜")
,值为阿李
时,未匹配中权重为0,值为藤训
时,匹配中第一个值权重为1,如果以正序排序,那么值越小权重越大,那么该值就会排在前面,倒叙权重则相反。
Java Comparator:
Comparator
一般有三个结果:负数、0、正数(一般是-1、0、1)。在正序排序中,值越少权重越大,即小于0的会排在前面。不过Comparator
的权重是由比较二者生成的,所以作用范围仅限本次对比。
如果,名单中的所有公司都交了广告费。
MySQL ORDER BY FIELD()
确定全部排序规则时,就无需处理权重=0的情况,因为每个字段的值都可以命中FIELD的下标:
SELECT *
FROM corporation
ORDER BY FIELD(`name`,"藤训","柏杜","阿李","孜洁","化为")
在Java中,只需要添加一个排序规则的列表用来定位下标从而判断顺序的大小即可:
List<String> corporation = Arrays.asList("化为","藤训","柏杜","阿李","孜洁");
List<String> sortRules = Arrays.asList("藤训","柏杜","阿李","孜洁","化为");
List<String> sorted = corporation.stream().sorted(((o1, o2) -> {
int i1 = sortRules.indexOf(o1);
int i2 = sortRules.indexOf(o2);
return i1 - i2;
})).collect(Collectors.toList());
结果如下:
排序前:
化为,藤训,柏杜,阿李,孜洁,
排序后:
藤训,柏杜,阿李,孜洁,化为,
假如部分公司不满自己交了钱还排靠后的位置,不再缴纳广告费。
这时,前面的排序规则可能在这种情况下就失效了,在MySQL中就会出现大批未命中下标的值排在前面:
我们稍微改一下代码,将权重=0的值都排在权重>0的后面:
SELECT *
FROM corporation
ORDER BY IF(FIELD(`name`,"藤训","柏杜") = 0 , 1, 0), FIELD(`name`,"藤训","柏杜")
在Java中的权重修改同理:
List<String> corporation = Arrays.asList("化为", "藤训", "柏杜", "阿李", "孜洁");
List<String> sortRules = Arrays.asList("藤训", "柏杜");
List<String> sorted = corporation.stream().sorted(((o1, o2) -> {
int i1 = sortRules.indexOf(o1);
int i2 = sortRules.indexOf(o2);
if (i1 < 0 || i2 < 0) {
return -(i1 - i2);
}
return i1 - i2;
})).collect(Collectors.toList());