自定义中文排序在Java中的实现与注意事项

目录

  • 前言
  • 1. 基本知识
  • 2. 实战

前言

#1024程序员节 | 征文#

在这里插入图片描述

对于Java的基本知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

原先的Java中文排序,推荐阅读:Java或者前端 实现中文排序(调API的Demo)

以下文章主要记录自定义实战的中文排序

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方法,以支持更复杂的模式
  • 兼容性排序
    可以考虑为英文字符或其他语言字符设置不同的排序逻辑,以满足多语言应用的需求
  • 负数处理
    如果存在负数表示,可以在提取汉字数字时加入相关逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/897487.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu(22.04)本地部署Appsmith

Ubuntu&#xff08;22.04&#xff09;安装Appsmith 简要介绍 Appsmith 是一个开源的低代码开发平台&#xff0c;旨在帮助开发者和非开发者快速构建定制化的内部应用程序和管理工具。通过直观的拖拽界面和丰富的预配置组件&#xff0c;Appsmith 让用户无需编写大量代码即可创建…

【C++】string类(2)

&#x1f973;个人主页: 起名字真南 &#x1f973;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 引言1 模拟实现string类基本框架2 实现string类中的主要成员函数2.1 Push_Back 函数2.2 reserve 函数2.3 append 函数2.4 c_str 函数2.5 begin ,end 函数2.5 operator 函数2.6…

IDEA开发工具使用技巧积累

一、IDEA 工具设置默认使用maven的settings.xml文件 第一步&#xff1a;打开idea工具&#xff0c;选中 File ——> New Projects Setup ——> Settings for New Projects 第二步&#xff1a;先设置下自动构建项目这个选项 第三步&#xff1a;选中 Build Tools ——>…

word删除空白页 | 亲测有效

想要删掉word里面的末尾空白页&#xff0c;但是按了delete之后也没有用 找了很久找到了以下亲测有效的方法 1. 通过鼠标右键在要删除的空白页面处显示段落标记 2. 在字号输入01&#xff0c;按ENTER&#xff08;回车键&#xff09; 3.成功删除了&#xff01;&#xff01; PS…

Selenium爬虫技术:如何模拟鼠标悬停抓取动态内容

介绍 在当今数据驱动的世界中&#xff0c;抓取动态网页内容变得越来越重要&#xff0c;尤其是像抖音这样的社交平台&#xff0c;动态加载的评论等内容需要通过特定的方式来获取。传统的静态爬虫方法难以处理这些由JavaScript生成的动态内容&#xff0c;Selenium爬虫技术则是一…

基于SSM大学校医院信息管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;校医管理&#xff0c;用户管理&#xff0c;在线问诊管理&#xff0c;线上挂号管理&#xff0c;病例记录管理&#xff0c;系统管理 校医账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xf…

用Java爬虫API,轻松获取taobao商品SKU信息

在电子商务的世界里&#xff0c;SKU&#xff08;Stock Keeping Unit&#xff0c;库存单位&#xff09;是商品管理的基础。对于商家来说&#xff0c;SKU的详细信息对于库存管理、价格策略制定、市场分析等都有着重要作用。taobao作为中国最大的电子商务平台之一&#xff0c;提供…

uniapp 微信小程序分包操作

1. 在项目根目录创建一个新的目录&#xff0c;名称为分包名称 2. 打开manifest.json&#xff0c;选择源码视图&#xff0c;加入以下代码 "optimization" : {"subPackages" : true } 3. 在pages.json中&#xff0c;pages后面添加分包代码 "subPackag…

Linux基础命令(入门)

linux 用户 root 用户 一个特殊的管理帐户 也被称为超级用户 root已接近完整的系统控制 对系统损害几乎有无限的能力 除非必要,不要登录为 root 普通&#xff08; 非特权 &#xff09; 用户权限有限 造成损害的能力比较有限 linux的哲学思想&#xff08;优点&#xf…

【Canvas与图标】制作电脑桌面图标

【成图】 制成的三种图标&#xff0c;都是120*120的。 制作时观察的大图 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>desk…

操作系统学习笔记2.1进程与线程

文章目录 概念 组成 特征状态与转换进程控制1. 进程的状态2. 进程控制块&#xff08;PCB&#xff09;3. 进程的创建与终止进程的创建进程的终止 4. 进程调度5. 进程间通信&#xff08;IPC&#xff09;6. 上下文切换 进程通信1. **管道&#xff08;Pipes&#xff09;**2. **信号…

C++ | Leetcode C++题解之第502题IPO

题目&#xff1a; 题解&#xff1a; typedef pair<int,int> pii;class Solution { public:int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {int n profits.size();int curr 0;priority_queue<int, vect…

Prometheus 告警

github alertmanager 文档 Prometheus Alerting rules Prometheus alerting configuration 前几篇文章讲了Prometheus的监控&#xff0c;这一篇文章&#xff0c;讲通过监控指标触发告警 常用的告警方式有发邮件、调用指定接口(webhook) 等。本文讲解webhook方式&#xff0c;完…

ARL 灯塔 | ARL 灯塔 — 字典替换

关注这个工具的其它相关内容&#xff1a;自动化信息收集工具 —— ARL 灯塔使用手册 - CSDN 博客 0x01&#xff1a;ARL 字典替换 —— 理论篇 ARL&#xff08;Asset Reconnaissance Lighthouse&#xff09;在进行目标域名探测时&#xff0c;依赖的是其内置的默认字典集。然而在…

从零开始:Python与Jupyter Notebook中的数据可视化之旅

目录 **理解数据与数据可视化的基本流程****了解Python与其他可视化工具****掌握Anaconda、Jupyter Notebook的常用操作方法****原理** 环境配置1. **安装Anaconda软件&#xff0c;创建实验环境**2. **安装Jupyter Notebook**3. **创建第一个Jupyter Notebook文本**&#xff08…

nnUnet 大模型学习笔记(续):训练网络(3d_fullres)以及数据集标签的处理

目录 1. 数据集处理 1.1 实现脚本 1.2 json文件 2. 设置读取路径 2.1 设置路径 2.2 数据集转换 2.3 数据集预处理 2.4 训练&#xff08;3d_fullres) 3. 训练结果展示 关于nnUnet 数据集的处理和环境搭建&#xff0c;参考上文&#xff1a;第四章&#xff1a;nnUnet大模…

94、Python之异常:自定义异常以满足业务个性化需求

引言 前面介绍了Python中内置的异常类的继承体系&#xff0c;通常来说&#xff0c;这些异常类已经能够满足各种异常的场景需要。但是&#xff0c;有时还是需要自定义异常&#xff0c;来满足一些个性化的需求&#xff0c;以及更加可控、精细化的异常管理。 本文就来介绍一下如…

使用InternVL、LMDeploy和GTE搭建多模态RAG系统

如何将视觉大模型&#xff08;VLM&#xff09;与 多模态RAG 结合起来&#xff0c;创建服装搜索和搭配推荐&#xff01;本文展示了InternVL模型在分析服装图像和提取颜色、款式和类型等关键特征方面的强大功能。 InternVL2是国内首个在MMMU(多学科问答)上突破60的模型&#xff0…

MT-Pref数据集:包含18种语言的18k实例,涵盖多个领域。实验表明它能有效提升Tower模型在WMT23和FLORES基准测试中的翻译质量。

2024-10-10&#xff0c;由电信研究所、里斯本大学等联合创建MT-Pref数据集&#xff0c;它包含18种语言方向的18k实例&#xff0c;覆盖了2022年后的多个领域文本。通过在WMT23和FLORES基准测试上的实验&#xff0c;我们展示了使用MT-Pref数据集对Tower模型进行对齐可以显著提高翻…

【云从】十、常见安全问题与云计算的计费模式

文章目录 1、常见安全问题1.1 DDoS攻击1.2 病毒攻击1.3 木马攻击1.4 代码自身漏洞 2、安全体系3、云计算的计费模式4、常见云产品的计费方案5、云产品计费案例 1、常见安全问题 1.1 DDoS攻击 通过分布在各地的大量终端&#xff0c;同时向目标发送恶意报包&#xff0c;以占满目…