本文介绍: 在业务开发过程,不免遇到一些比较复杂的排序场景:按学生姓名拼音首字母排序,按英文字顺序排序,如果是中英混合还期望先按英文排序、再按中文排序……本文将针对这些场景提供对应的解决方式。
背景
在业务开发过程,不免遇到一些比较复杂的排序场景:按学生姓名拼音首字母排序,按英文字顺序排序,如果是中英混合还期望先按英文排序、再按中文排序…本文将针对这些场景提供对应的解决方式。
实践
- 按拼音首字母排序、或者混合着数字和英文
这里我们借助pinyin4j工具包
<!-- https://mvnrepository.com/artifact/com.belerweb/pinyin4j -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
</dependency>
- 如下我们提供的compareByPinyin方法,会对两个字符串进行比较并返回一个int类型数值,大于0时,表示compareStr1在compareStr2前面。
- 当有英文和数字时,下面方法默认会**按数字->英文->中文顺序排序,**如”赫尔”, “123C里昂”, “C肯尼”,排序后是”123C里昂”、“C肯尼”、“赫尔”。
- 注意!这里借助pinyin4j获取的拼音结果会带声调的,比如同音情况下,“赫尔”, “喝水”, “荷花”,结果将返回 “he4er3”,“he1shui3”,“he2hua1”,由于此时带有**数字,**造成排序结果会是 **“喝水”,“荷花”,“赫尔”,**业务使用时,还是需要结合实际情况,看看需不需要过滤数字
fun main() {
val result = listOf("赫尔", "里昂", "肯尼").sortedWith(
Comparator { o1, o2 ->
SortUtil.compareByPinyinAndDigital(o1, o2)
}
)
result.forEach {
println(it) //赫尔、肯尼、里昂
}
}
fun compareByPinyin(compareStr1: String, compareStr2: String): Int {
val str1 = getPinyinInitials(compareStr1).toLowerCase()
val str2 = getPinyinInitials(compareStr2).toLowerCase()
return str1.compareTo(str2)
}
/**
* 获取拼音
*
* @param text 文本
* @return {@link String}
*/
private fun getPinyinInitials(text: String): String {
val sb = StringBuilder()
for (c in text) {
val pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c)
if (pinyinArray != null && pinyinArray.isNotEmpty()) {
sb.append(pinyinArray.first())
} else {
sb.append(c)
}
}
return sb.toString()
}
- 上面的排序是固定**数字->英文->中文顺序排序,**如果想按照自定义规则排序,那么我们可以考虑如下的方式
- 这里相当于把首字符拆出来,如果都是中文,就走中文比较,如果不是,两个字符类型又都相同(都是数字或者都是字母),就走正常比较逻辑,否则**type[i]的值比较,保证中文>英文>数字>null **顺序。
- 注意!这里的中文比较用的是Collator类,在Java里,采用的是UNICODE编码,而对于中文的UNICODE字符集,它是源于GB18030的,而GB18030又发展自GB2312,GB2312收录的中文字符个数大概6763个汉字,按照拼音排序,并且是连续的。如果是非这个字符集收录的汉字排序可能就会乱,如果对这个要求严格可能得考虑pinyin4j。
fun main() {
val result = listOf("12赫尔", "av喝水", "荷花", "黑王").sortedWith(
Comparator { o1, o2 ->
SortUtil.sortByCustomRegular(o1, o2)
}
)
result.forEach {
println(it) // 荷花 黑王 av喝水 12赫尔
}
}
/**
* 定制的排序规则
* 等第制的排序规则
* 中文>英文>数字>null
*
* @param compareStr1
* @param compareStr2
* @return
*/
companion object {
fun sortByCustomRegular(compareStr1: String?, compareStr2: String?): Int {
if (StringUtils.isBlank(compareStr1)) {
return 1
}
if (StringUtils.isBlank(compareStr2)) {
return -1
}
val c = charArrayOf(compareStr1!!.toLowerCase()[0], compareStr2!!.toLowerCase()[0])//首字母
val str = arrayOf(compareStr1.substring(0, 1), compareStr2.substring(0, 1))
val type = intArrayOf(1, 1)
//判断两个字符串是什么类型
for (i in 0..1) {
when {
//中文字符
str[i].matches("[\u4e00-\u9fbb]+".toRegex()) -> type[i] = 1
c[i] in 'a'..'z' -> type[i] = 2
c[i] in '1'..'9' -> type[i] = 3
else -> type[i] = 4
}
}
//比较两个中文
if (type[0] == 2 && type[1] == 2)
return Collator.getInstance(Locale.CHINA).compare(compareStr1, compareStr2)
//比较两个英文,比较中文和英文
return if (type[0] == type[1]) compareStr1.compareTo(compareStr2) else type[0] - type[1]
}
原文地址:https://blog.csdn.net/legendaryhaha/article/details/135466033
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_53798.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。