Java实现自定义中文排序的方法机注意事项

 更新时间:2024年10月24日 10:03:39   作者:码农研究僧  
在Java中,中文排序通常涉及到使用Collator类来处理字符串的比较,确保根据汉字的拼音顺序进行排序,本文给大家介绍了Java实现自定义中文排序的方法机注意事项,并有相关的代码示例供大家参考,需要的朋友可以参考下

1. 基本知识

在Java中,中文排序通常涉及到使用Collator类来处理字符串的比较,确保根据汉字的拼音顺序进行排序

以下是详细分析和示例代码:(上述链接文章已经说清楚了,但先讲解一遍浅显的知识)

  • Collator类:用于比较字符串,特别适用于处理不同语言的排序
  • Locale:指定语言环境,影响排序规则
  • compare方法:用于比较两个字符串,根据指定的语言环境返回排序结果

示例代码如下:

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

public class ChineseSortingDemo {
    public static void main(String[] args) {
        // 创建一个包含中文字符串的列表
        List<String> chineseNames = new ArrayList<>();
        chineseNames.add("张三");
        chineseNames.add("李四");
        chineseNames.add("王五");
        chineseNames.add("赵六");

        // 获取中文排序的Collator实例
        Collator collator = Collator.getInstance(Locale.CHINESE);

        // 对列表进行排序
        Collections.sort(chineseNames, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return collator.compare(o1, o2); // 使用Collator比较
            }
        });

        // 输出排序后的结果
        System.out.println("排序后的中文名字:");
        for (String name : chineseNames) {
            System.out.println(name);
        }
    }
}

基本的逻辑如下:

  1. 导入所需类:导入Collator、ArrayList、Collections、Comparator和Locale
  2. 创建列表:使用ArrayList来存储中文字符串
  3. 获取Collator实例:使用Collator.getInstance(Locale.CHINESE)来获取适用于中文的排序规则
  4. 排序操作:通过Collections.sort()和自定义比较器,使用collator.compare()进行排序

2. 实战

自定义中文排序通常涉及对字符串的特定部分进行比较,以满足业务需求

主要目标是按照特定的中文数字(如“一”、“二”等)和名称排序,逻辑如下

  1. 提取数字部分:通过extractChineseNumber方法,从每个字符串中提取汉字数字部分。如果字符串包含汉字数字,则优先根据这些数字排序
  2. 排序优先级:首先,包含“类”的项优先。其次,根据提取的汉字数字进行排序,使用自定义比较器来定义排序规则。
    最后,对于没有数字的项,按字典顺序排序
  3. 使用流式处理:通过Java 8的流式API进行排序,增强代码的可读性和简洁性

注意事项

  • 字符集:确保输入的字符串都为标准汉字,避免因字符集不同导致的排序错误
  • 性能:在处理大量数据时,排序操作可能会影响性能,尽量优化提取逻辑
  • 多样性:考虑到可能存在的多种中文数字(如“零”)和不同的业务需求,确保排序规则的灵活性
  • 边界情况:处理字符串中可能没有汉字数字的情况,避免空指针异常
// 查询所有数据,不进行分页
List<Sort> allRecords = sortService.list(queryWrapper);

// 自定义中文数字排序规则
Comparator<String> chineseNumberComparator = (a, b) -> {
    String[] chineseNumbers = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
    List<String> chineseNumberList = Arrays.asList(chineseNumbers);

    // 获取字符串的汉字数字部分
    String aNumberPart = extractChineseNumber(a);
    String bNumberPart = extractChineseNumber(b);

    // 如果都包含汉字数字部分,则按自定义顺序排序
    if (chineseNumberList.contains(aNumberPart) && chineseNumberList.contains(bNumberPart)) {
        return Integer.compare(chineseNumberList.indexOf(aNumberPart), chineseNumberList.indexOf(bNumberPart));
    }
    // 如果只有一个包含汉字数字,优先含有数字的排序
    else if (chineseNumberList.contains(aNumberPart)) {
        return -1;
    } else if (chineseNumberList.contains(bNumberPart)) {
        return 1;
    }
    // 如果都不包含汉字数字,则按字典序排序
    return a.compareTo(b);
};

// 对所有记录进行排序
List<Sort> sortedRecords = allRecords.stream()
    .sorted(Comparator.comparing((Sort record) -> {
            String sortNameRecord = record.getSortName();
            // 首先检查是否包含“类”,并提取类的前缀
            boolean hasClass = sortNameRecord.contains("类");
            // 确保包含“类”的项优先
            return hasClass ? 0 : 1; // 优先级
        })
        .thenComparing(Comparator.comparing((Sort record) -> {
            String sortNameRecord = record.getSortName();
            // 如果包含“类”,提取汉字数字部分并按其索引排序
            if (sortNameRecord.contains("类")) {
                return extractChineseNumber(sortNameRecord); // 提取汉字数字部分
            }
            return ""; // 没有类的项返回空字符串以放置在最后
        }, chineseNumberComparator)) // 按汉字数字排序
        .thenComparing(Comparator.comparing(Sort::getSortName)) // 按名称进行自然排序
    )
    .collect(Collectors.toList());

/**
 * 提取字符串中的汉字数字部分
 */
private String extractChineseNumber(String str) {
    String[] chineseNumbers = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
    for (String number : chineseNumbers) {
        if (str.contains(number)) {
            return number;
        }
    }
    return ""; // 如果没有汉字数字,返回空字符串
}

截图如下:

最终效果如下:

测试的总体Demo如下:

import java.util.*;
import java.util.stream.Collectors;

public class CustomChineseSorting {
    public static void main(String[] args) {
        List<Sort> allRecords = sortService.list(queryWrapper);
        
        // 自定义中文数字排序规则
        Comparator<String> chineseNumberComparator = (a, b) -> {
            String[] chineseNumbers = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "零"};
            List<String> chineseNumberList = Arrays.asList(chineseNumbers);

            String aNumberPart = extractChineseNumber(a);
            String bNumberPart = extractChineseNumber(b);

            if (chineseNumberList.contains(aNumberPart) && chineseNumberList.contains(bNumberPart)) {
                return Integer.compare(chineseNumberList.indexOf(aNumberPart), chineseNumberList.indexOf(bNumberPart));
            } else if (chineseNumberList.contains(aNumberPart)) {
                return -1;
            } else if (chineseNumberList.contains(bNumberPart)) {
                return 1;
            }
            return a.compareTo(b);
        };

        // 对所有记录进行排序
        List<Sort> sortedRecords = allRecords.stream()
            .sorted(Comparator.comparing((Sort record) -> {
                    String sortNameRecord = record.getSortName();
                    return sortNameRecord.contains("类") ? 0 : 1;
                })
                .thenComparing(Comparator.comparing((Sort record) -> {
                    String sortNameRecord = record.getSortName();
                    if (sortNameRecord.contains("类")) {
                        return extractChineseNumber(sortNameRecord);
                    }
                    return ""; 
                }, chineseNumberComparator))
                .thenComparing(Comparator.comparing(Sort::getSortName))
            )
            .collect(Collectors.toList());

        // 输出排序后的结果
        sortedRecords.forEach(record -> System.out.println(record.getSortName()));
    }

    // 提取字符串中的汉字数字部分
    private static String extractChineseNumber(String str) {
        String[] chineseNumbers = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
        for (String number : chineseNumbers) {
            if (str.contains(number)) {
                return number;
            }
        }
        return ""; 
    }
}

主要的注意事项如下:

  • 处理多个汉字数字
    若需要处理更大的数字(如“十一”、“十二”等),可进一步扩展extractChineseNumber方法,以支持更复杂的模式
  • 兼容性排序
    可以考虑为英文字符或其他语言字符设置不同的排序逻辑,以满足多语言应用的需求
  • 负数处理
    如果存在负数表示,可以在提取汉字数字时加入相关逻辑

到此这篇关于Java实现自定义中文排序的方法机注意事项的文章就介绍到这了,更多相关Java自定义中文排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Jenkins初级使用过程中的异常处理

    Jenkins初级使用过程中的异常处理

    这篇文章主要为大家介绍了Jenkins初级使用过程中的异常处理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Mybatis Plus 中的LambdaQueryWrapper示例详解

    Mybatis Plus 中的LambdaQueryWrapper示例详解

    这篇文章主要介绍了Mybatis Plus 中的LambdaQueryWrapper,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • SpringBoot的reload加载器的方法

    SpringBoot的reload加载器的方法

    本篇文章主要介绍了SpringBoot的reload加载器的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • 简单谈谈java中匿名内部类构造函数

    简单谈谈java中匿名内部类构造函数

    这篇文章主要简单给我们介绍了java中匿名内部类构造函数,并附上了简单的示例,有需要的小伙伴可以参考下。
    2015-11-11
  • struts1登录示例代码_动力节点Java学院整理

    struts1登录示例代码_动力节点Java学院整理

    这篇文章主要介绍了struts1登录示例代码,需要的朋友可以参考下
    2017-08-08
  • 解决SpringBoot运行报错:找不到或无法加载主类的问题

    解决SpringBoot运行报错:找不到或无法加载主类的问题

    这篇文章主要介绍了解决SpringBoot运行报错:找不到或无法加载主类的问题,具有很好的参考价值,对大家的学习或工作有一定的参考价值,需要的朋友可以参考下
    2023-09-09
  • 如何通过Java打印Word文档

    如何通过Java打印Word文档

    这篇文章主要介绍了如何通过Java打印Word文档,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Spring整合Quartz实现定时任务调度的方法

    Spring整合Quartz实现定时任务调度的方法

    下面小编就为大家带来一篇Spring整合Quartz实现定时任务调度的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • log4j配置失效日志中打印Debug信息问题

    log4j配置失效日志中打印Debug信息问题

    这篇文章主要介绍了log4j配置失效日志中打印Debug信息问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • drools规则动态化实践解析

    drools规则动态化实践解析

    这篇文章主要为大家介绍了drools规则动态化实践解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02

最新评论