使用Java对中文首字母进行排序

前言

最近由于工作需求,需要对行政区划根据中文首字母进行排序,在网上查了些资料,没有什么收获,基本上都是千篇一律、相互“借鉴”。因此本人在此做一个整理,以备后续不时之需。
废话不多说,直接上代码。

代码

创建如下实体类用来构造测试数据:

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public 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>() {
            @Override
            public int compare(DemoDomain o1, DemoDomain o2) {
               /**
                 * 设置中文环境
                 * Collator 类的具体用法参考官网
                 * https://docs.oracle.com/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>() {
            @Override
            public 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 nameOne.compareTo(nameTwo);
            }
        });
        list.forEach(demoDomain -> {
            System.out.println(demoDomain.getName());
        });
    }
重庆市
焦作市
开封市
南阳市
濮阳市
三门峡市
漯河市
郑州市

你可能感兴趣的:(解决的小问题,java)