前言
最近由于工作需求,需要对行政区划根据中文首字母进行排序,在网上查了些资料,没有什么收获,基本上都是千篇一律、相互“借鉴”。因此本人在此做一个整理,以备后续不时之需。
废话不多说,直接上代码。
代码
创建如下实体类用来构造测试数据:
import lombok.AllArgsConstructor;import lombok.Data;@Data@AllArgsConstructorpublic class DemoDomain {/*** 名称*/private String name;/*** 数量*/private Integer num;}
main方法
为了简单,我直接在Java的main方法中进行简单的测试:
public static void main(String[] args) {List<DemoDomain> list = new ArrayList<>();//DemoDomain a = new DemoDomain("漯河市", 100);//DemoDomain b = new DemoDomain("濮阳市", 200);DemoDomain c = new DemoDomain("开封市", 130);DemoDomain d = new DemoDomain("郑州市", 290);DemoDomain e = new DemoDomain("南阳市", 300);DemoDomain f = new DemoDomain("焦作市", 412);DemoDomain g = new DemoDomain("三门峡市", 234);//DemoDomain h = new DemoDomain("重庆市", 110);//list.add(a);//list.add(b);list.add(c);list.add(d);list.add(e);list.add(f);list.add(g);//list.add(h);//通过集合工具类的sort方法进行排序Collections.sort(list, new Comparator<DemoDomain>() {@Overridepublic int compare(DemoDomain o1, DemoDomain o2) {/*** 设置中文环境* Collator 类的具体用法参考官网* /javase/7/docs/api/java/text/Collator.html*/Collator collator = Collator.getInstance(java.util.Locale.CHINA);return collator.getCollationKey(o1.getName()).compareTo(collator.getCollationKey(o2.getName()));}});list.forEach(demoDomain -> {System.out.println(demoDomain.getName());});}
也许大家觉得上边的写法没问题,在一些特定情况下,上边确实的代码确实是没问题。比如在将对象a、b、h注释掉的情况下输出的情况确实是按照首字母进行排序的;
焦作市开封市南阳是三门峡市郑州市
但是将注释放开,再次运行,却发现并不是我们预想的结果:
焦作市开封市南阳市三门峡市郑州市重庆市 漯河市濮阳市
重庆市 、漯河市、濮阳市排在了后边,这明显是不正确的。个人觉得有可能是多音字的原因。为了解决这个问题,可以引入如下jar包:
<dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.1</version></dependency>
main方法改为如下方式,再次执行,即可正确输出。
public static void main(String[] args) {List<DemoDomain> list = new ArrayList<>();DemoDomain a = new DemoDomain("漯河市", 100);DemoDomain b = new DemoDomain("濮阳市", 200);DemoDomain c = new DemoDomain("开封市", 130);DemoDomain d = new DemoDomain("郑州市", 290);DemoDomain e = new DemoDomain("南阳市", 300);DemoDomain f = new DemoDomain("焦作市", 412);DemoDomain g = new DemoDomain("三门峡市", 234);DemoDomain h = new DemoDomain("重庆市", 234);list.add(a);list.add(b);list.add(c);list.add(d);list.add(e);list.add(f);list.add(g);list.add(h);HanyuPinyinOutputFormat pinyinOutputFormat = new HanyuPinyinOutputFormat();Collections.sort(list, new Comparator<DemoDomain>() {@Overridepublic int compare(DemoDomain o1, DemoDomain o2) {String nameOne = "";String nameTwo = "";try {nameOne = PinyinHelper.toHanYuPinyinString(o1.getName(), pinyinOutputFormat, " ", true);nameTwo = PinyinHelper.toHanYuPinyinString(o2.getName(), pinyinOutputFormat, " ", true);} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {badHanyuPinyinOutputFormatCombination.printStackTrace();}return pareTo(nameTwo);}});list.forEach(demoDomain -> {System.out.println(demoDomain.getName());});}
重庆市焦作市开封市南阳市濮阳市三门峡市漯河市郑州市