Java8对中文汉字排序的Comparator实现类

x33g5p2x  于2021-12-06 转载在 Java  
字(2.8k)|赞(0)|评价(0)|浏览(525)

最近由于工作需要需要对中文汉字排序,编写了Comparator实现类分享给大家。

直接上代码:

import java.util.Comparator;

public class ChineseComparator<T> implements Comparator<T> {

    private static boolean isDigit(char ch) {
        return ch >= 48 && ch <= 57;
    }

    /**
     * Length of string is passed in for improved efficiency (only need to calculate it once)
     **/
    private static String getChunk(String s, int slength, int marker) {
        StringBuilder chunk = new StringBuilder();
        int index = marker;
        char c = s.charAt(index);
        chunk.append(c);
        index++;
        if (isDigit(c)) {
            while (index < slength) {
                c = s.charAt(index);
                if (!isDigit(c)) {
                    break;
                }
                chunk.append(c);
                index++;
            }
        } else {
            while (index < slength) {
                c = s.charAt(index);
                if (isDigit(c)) {
                    break;
                }
                chunk.append(c);
                index++;
            }
        }
        return chunk.toString();
    }

    @Override
    public int compare(Object o1, Object o2) {
        if (!(o1 instanceof String) || !(o2 instanceof String)) {
            return 0;
        }
        String s1 = (String) o1;
        String s2 = (String) o2;

        return compareString(s1,s2);
    }

    public static int compareString(String s1,String s2){
        if(s1 == null){
            return 1;
        }
        if(s2 == null){
            return -1;
        }
        int thisMarker = 0;
        int thatMarker = 0;
        int s1Length = s1.length();
        int s2Length = s2.length();

        while (thisMarker < s1Length && thatMarker < s2Length) {
            String thisChunk = getChunk(s1, s1Length, thisMarker);
            thisMarker += thisChunk.length();

            String thatChunk = getChunk(s2, s2Length, thatMarker);
            thatMarker += thatChunk.length();

            //如果两个字符块都是数字,则按数字排序
            int result;
            if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) {
                result = compareDigit(thisChunk,thatChunk);
                if (result != 0) {
                    return result;
                }
            } else {
                result = thisChunk.compareTo(thatChunk);
            }

            if (result != 0) {
                return result;
            }
        }

        return s1Length - s2Length;
    }

    /**
     * 按数字比较
     */
    private static int compareDigit(String thisChunk,String thatChunk){
        int thisChunkLength = thisChunk.length();
        int result = thisChunkLength - thatChunk.length();
        if (result == 0) {
            //诸位比较
            for (int i = 0; i < thisChunkLength; i++) {
                result = thisChunk.charAt(i) - thatChunk.charAt(i);
                if (result != 0) {
                    return result;
                }
            }
        }
        return result;
    }

}

使用方法:

public static void main(String[] args) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("name", "高一(1)班");
        map.put("age", 13);

        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("name", "高一(11)班");
        map2.put("age", 15);

        Map<String, Object> map3 = new HashMap<String, Object>();
        map3.put("name", "高一(1)班");
        map3.put("age", 20);

        Map<String, Object> map4 = new HashMap<String, Object>();
        map4.put("name", "高一(2)班");
        map4.put("age", 18);

        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        list.add(map);
        list.add(map2);
        list.add(map3);
        list.add(map4);
        System.out.println("排序前:"+list);
        List<Map> collect =
                list.stream().sorted((o1, o2) -> ChineseComparator.compareString(o1.get("name")+"",o2.get("name")+""))
                        .collect(Collectors.toList());

        System.out.println("排序后:"+collect);
    }

运行结果如下:


 

相关文章