Java實(shí)現(xiàn)自定義中文排序的方法機(jī)注意事項(xiàng)
1. 基本知識(shí)
在Java中,中文排序通常涉及到使用Collator類來處理字符串的比較,確保根據(jù)漢字的拼音順序進(jìn)行排序
以下是詳細(xì)分析和示例代碼:(上述鏈接文章已經(jīng)說清楚了,但先講解一遍淺顯的知識(shí))
- Collator類:用于比較字符串,特別適用于處理不同語(yǔ)言的排序
- Locale:指定語(yǔ)言環(huán)境,影響排序規(guī)則
- compare方法:用于比較兩個(gè)字符串,根據(jù)指定的語(yǔ)言環(huán)境返回排序結(jié)果
示例代碼如下:
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) { // 創(chuàng)建一個(gè)包含中文字符串的列表 List<String> chineseNames = new ArrayList<>(); chineseNames.add("張三"); chineseNames.add("李四"); chineseNames.add("王五"); chineseNames.add("趙六"); // 獲取中文排序的Collator實(shí)例 Collator collator = Collator.getInstance(Locale.CHINESE); // 對(duì)列表進(jìn)行排序 Collections.sort(chineseNames, new Comparator<String>() { @Override public int compare(String o1, String o2) { return collator.compare(o1, o2); // 使用Collator比較 } }); // 輸出排序后的結(jié)果 System.out.println("排序后的中文名字:"); for (String name : chineseNames) { System.out.println(name); } } }
基本的邏輯如下:
- 導(dǎo)入所需類:導(dǎo)入Collator、ArrayList、Collections、Comparator和Locale
- 創(chuàng)建列表:使用ArrayList來存儲(chǔ)中文字符串
- 獲取Collator實(shí)例:使用Collator.getInstance(Locale.CHINESE)來獲取適用于中文的排序規(guī)則
- 排序操作:通過Collections.sort()和自定義比較器,使用collator.compare()進(jìn)行排序
2. 實(shí)戰(zhàn)
自定義中文排序通常涉及對(duì)字符串的特定部分進(jìn)行比較,以滿足業(yè)務(wù)需求
主要目標(biāo)是按照特定的中文數(shù)字(如“一”、“二”等)和名稱排序,邏輯如下
- 提取數(shù)字部分:通過extractChineseNumber方法,從每個(gè)字符串中提取漢字?jǐn)?shù)字部分。如果字符串包含漢字?jǐn)?shù)字,則優(yōu)先根據(jù)這些數(shù)字排序
- 排序優(yōu)先級(jí):首先,包含“類”的項(xiàng)優(yōu)先。其次,根據(jù)提取的漢字?jǐn)?shù)字進(jìn)行排序,使用自定義比較器來定義排序規(guī)則。
最后,對(duì)于沒有數(shù)字的項(xiàng),按字典順序排序 - 使用流式處理:通過Java 8的流式API進(jìn)行排序,增強(qiáng)代碼的可讀性和簡(jiǎn)潔性
注意事項(xiàng)
- 字符集:確保輸入的字符串都為標(biāo)準(zhǔn)漢字,避免因字符集不同導(dǎo)致的排序錯(cuò)誤
- 性能:在處理大量數(shù)據(jù)時(shí),排序操作可能會(huì)影響性能,盡量?jī)?yōu)化提取邏輯
- 多樣性:考慮到可能存在的多種中文數(shù)字(如“零”)和不同的業(yè)務(wù)需求,確保排序規(guī)則的靈活性
- 邊界情況:處理字符串中可能沒有漢字?jǐn)?shù)字的情況,避免空指針異常
// 查詢所有數(shù)據(jù),不進(jìn)行分頁(yè) List<Sort> allRecords = sortService.list(queryWrapper); // 自定義中文數(shù)字排序規(guī)則 Comparator<String> chineseNumberComparator = (a, b) -> { String[] chineseNumbers = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"}; List<String> chineseNumberList = Arrays.asList(chineseNumbers); // 獲取字符串的漢字?jǐn)?shù)字部分 String aNumberPart = extractChineseNumber(a); String bNumberPart = extractChineseNumber(b); // 如果都包含漢字?jǐn)?shù)字部分,則按自定義順序排序 if (chineseNumberList.contains(aNumberPart) && chineseNumberList.contains(bNumberPart)) { return Integer.compare(chineseNumberList.indexOf(aNumberPart), chineseNumberList.indexOf(bNumberPart)); } // 如果只有一個(gè)包含漢字?jǐn)?shù)字,優(yōu)先含有數(shù)字的排序 else if (chineseNumberList.contains(aNumberPart)) { return -1; } else if (chineseNumberList.contains(bNumberPart)) { return 1; } // 如果都不包含漢字?jǐn)?shù)字,則按字典序排序 return a.compareTo(b); }; // 對(duì)所有記錄進(jìn)行排序 List<Sort> sortedRecords = allRecords.stream() .sorted(Comparator.comparing((Sort record) -> { String sortNameRecord = record.getSortName(); // 首先檢查是否包含“類”,并提取類的前綴 boolean hasClass = sortNameRecord.contains("類"); // 確保包含“類”的項(xiàng)優(yōu)先 return hasClass ? 0 : 1; // 優(yōu)先級(jí) }) .thenComparing(Comparator.comparing((Sort record) -> { String sortNameRecord = record.getSortName(); // 如果包含“類”,提取漢字?jǐn)?shù)字部分并按其索引排序 if (sortNameRecord.contains("類")) { return extractChineseNumber(sortNameRecord); // 提取漢字?jǐn)?shù)字部分 } return ""; // 沒有類的項(xiàng)返回空字符串以放置在最后 }, chineseNumberComparator)) // 按漢字?jǐn)?shù)字排序 .thenComparing(Comparator.comparing(Sort::getSortName)) // 按名稱進(jìn)行自然排序 ) .collect(Collectors.toList()); /** * 提取字符串中的漢字?jǐn)?shù)字部分 */ private String extractChineseNumber(String str) { String[] chineseNumbers = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"}; for (String number : chineseNumbers) { if (str.contains(number)) { return number; } } return ""; // 如果沒有漢字?jǐn)?shù)字,返回空字符串 }
截圖如下:
最終效果如下:
測(cè)試的總體Demo如下:
import java.util.*; import java.util.stream.Collectors; public class CustomChineseSorting { public static void main(String[] args) { List<Sort> allRecords = sortService.list(queryWrapper); // 自定義中文數(shù)字排序規(guī)則 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); }; // 對(duì)所有記錄進(jìn)行排序 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()); // 輸出排序后的結(jié)果 sortedRecords.forEach(record -> System.out.println(record.getSortName())); } // 提取字符串中的漢字?jǐn)?shù)字部分 private static String extractChineseNumber(String str) { String[] chineseNumbers = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"}; for (String number : chineseNumbers) { if (str.contains(number)) { return number; } } return ""; } }
主要的注意事項(xiàng)如下:
- 處理多個(gè)漢字?jǐn)?shù)字:
若需要處理更大的數(shù)字(如“十一”、“十二”等),可進(jìn)一步擴(kuò)展extractChineseNumber方法,以支持更復(fù)雜的模式 - 兼容性排序:
可以考慮為英文字符或其他語(yǔ)言字符設(shè)置不同的排序邏輯,以滿足多語(yǔ)言應(yīng)用的需求 - 負(fù)數(shù)處理:
如果存在負(fù)數(shù)表示,可以在提取漢字?jǐn)?shù)字時(shí)加入相關(guān)邏輯
到此這篇關(guān)于Java實(shí)現(xiàn)自定義中文排序的方法機(jī)注意事項(xiàng)的文章就介紹到這了,更多相關(guān)Java自定義中文排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis?Plus?中的LambdaQueryWrapper示例詳解
這篇文章主要介紹了Mybatis?Plus?中的LambdaQueryWrapper,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03簡(jiǎn)單談?wù)刯ava中匿名內(nèi)部類構(gòu)造函數(shù)
這篇文章主要簡(jiǎn)單給我們介紹了java中匿名內(nèi)部類構(gòu)造函數(shù),并附上了簡(jiǎn)單的示例,有需要的小伙伴可以參考下。2015-11-11struts1登錄示例代碼_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了struts1登錄示例代碼,需要的朋友可以參考下2017-08-08解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無法加載主類的問題
這篇文章主要介紹了解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無法加載主類的問題,具有很好的參考價(jià)值,對(duì)大家的學(xué)習(xí)或工作有一定的參考價(jià)值,需要的朋友可以參考下2023-09-09Spring整合Quartz實(shí)現(xiàn)定時(shí)任務(wù)調(diào)度的方法
下面小編就為大家?guī)硪黄猄pring整合Quartz實(shí)現(xiàn)定時(shí)任務(wù)調(diào)度的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11drools規(guī)則動(dòng)態(tài)化實(shí)踐解析
這篇文章主要為大家介紹了drools規(guī)則動(dòng)態(tài)化實(shí)踐解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02