论如何对既包含中文又包含英文的集合按照字母进行排序????

  最近在做项目的时候遇到了一个针对集合需要按字母从a到z进行排序的问题,可是集合中的元素有的全是英文,有的全是中文,而有的还是中英文结合,上网搜了一下第一反应用的是Collator,对于什么是Collator大家可以上网搜索了解一下,这里就不做详细介绍了。

   但是Collator有一个问题,就是Java并不能精确的对所有的汉字进行排序,比如对“犇”和“鑫”进行排序,只是因为我们的汉字文化太博大精深了,要做好这个排序确实有点难为Java了。更深层次的原因是Java使用的是 UNICODE 编码,而中文 UNICODE 字符集是来源于 GB18030 的,GB18030 又是从GB2312 发展起来的, GB2312 是一个包含 7000 多个字符的字符集,它是按照拼音排序,并且是连续的,之后的 GBK、GB2312 都是在起基础上扩充而来的,所以要让它们完整排序也就难上加难了。但如果排序对象是经常使用的汉字,使用Collator类排序完全可以满足我们的要求。 如果需要严格排序,可以使用一些开源项目来自己实现,比如 pinyin4j 可以把汉字转换为拼音,然后我们自己来实现排序算法,不过此时你也会发现要考虑诸如算法、同音字、多音字等众多问题。 pinyin4j下载地址:http://pinyin4j.sourceforge.net/, 嗯哼,这句话也不是我说的,是这篇博客:https://blog.csdn.net/u010039979/article/details/53583445

  然后,我就尝试使用pinyin4j编写了一个比较器,下面具体说一下:

 1.首先添加pom依赖

 <!-- https://mvnrepository.com/artifact/com.belerweb/pinyin4j -->
    <dependency>
      <groupId>com.belerweb</groupId>
      <artifactId>pinyin4j</artifactId>
      <version>2.5.0</version>
    </dependency>

2.编写比较器:代码如下

package com.xh.list;

import net.sourceforge.pinyin4j.PinyinHelper;

import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author:
 * @Description
 * @Date: 2018/9/10 13:59
 */
public class HanYuPinYinComparator implements Comparator<String> {
    //调用pinyin4j工具类
    private String concatPinyinStringArray(String[] pinyinArray) {
        StringBuffer pinyinSbf = new StringBuffer();
        if ((pinyinArray != null) && (pinyinArray.length > 0)) {
            for (int i = 0; i < pinyinArray.length; i++) {
                pinyinSbf.append(pinyinArray[i]);
            }
        }
        return pinyinSbf.toString();
    }

    @Override
    public int compare(String o1, String o2) {
        if (o1 == null || o2 == null || o1.equals("") || o2.equals("") || o1.equals(o2)) return 0;
        //以汉字少的为基准
        for(int i = 0; i < Math.min(o1.length(), o2.length()); i++){
            char c1 = o1.charAt(i);
            char c2 = o2.charAt(i);
            if(isChinese(c1+"") && isChinese(c2+"")){//比较两个字符都是汉字的情况
                int result = concatPinyinStringArray(
                        PinyinHelper.toHanyuPinyinStringArray(c1)).compareToIgnoreCase(
                        concatPinyinStringArray(PinyinHelper
                                .toHanyuPinyinStringArray(c2)));
                //如果比较结果相同,就比较下一个汉字
                if(result == 0){
                    continue;
                }
                return result;
            }else if(isChinese(c1+"") && !isChinese(c2+"")){//比较前者是汉字后者为非汉字的情况
                int result = (concatPinyinStringArray(PinyinHelper
                        .toHanyuPinyinStringArray(c1))).compareToIgnoreCase(c2+"");
                if(result == 0){
                    continue;
                }
                return result;
            }else if(!isChinese(c1+"") && isChinese(c2+"")){//比较后者是汉字前者为非汉字的情况
                int result =(c1+"").compareToIgnoreCase(concatPinyinStringArray(PinyinHelper
                        .toHanyuPinyinStringArray(c2)));
                if(result == 0){
                    continue;
                }
                return result;
            }else {//比较
                int result = (c1+"").compareToIgnoreCase(c2+"");
                if(result == 0){
                    continue;
                }
                  return result;
            }
        }
        //如果程序执行到这行两个字符串相比较的部分都相同,那么字符串长度长的定义为大
        return (o1.length() - o2.length())<0?-1:(o1.length() - o2.length())==0?0:1;
    }
    /**
     * 判断是否为汉字
     * @param str 字
     * @return
     */
    public  boolean isChinese(String str) {
        Pattern p_str = Pattern.compile("[\\u4e00-\\u9fa5]+");
        Matcher m = p_str.matcher(str);
        if(m.find()&&m.group(0).equals(str)){
            return true;
        }
        return false;
    }
}

3.编写一个测试demo测试一下:

package com.xh.list;

import java.text.Collator;
import java.util.*;


public class TestDemo {
    public static void main(String[] args){
        List<String> list = new ArrayList<>();
        list.add("呲牙");
        list.add("震惊");
        list.add("尴尬");
        list.add("haha菠菜");
        list.add("喵喵");
        list.add("咒骂");
        list.add("aaaa这是");
        list.add("蝙蝠侠");
        list.add("aa");
        Collections.sort(list, new HanYuPinYinComparator());
        for(String str:list){
            System.out.println(str);
        }
    }
}

4.观察一下输出结果吧:

aa
aaaa这是
蝙蝠侠
呲牙
尴尬
haha菠菜
喵喵
震惊
咒骂

Process finished with exit code 0

完美解决!!!希望能帮到该需求的小伙伴

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Java中的Comparator接口来实现自定义排序。具体步骤如下: 1. 创建一个实现Comparator接口的类,该类中需要实现compare方法来定义排序规则。 2. 在compare方法中,首先判断排序的内容属于哪种类型(数组、英文、符号),然后分别进行比较排序。 3. 将排序后的结果返回。 下面是一个示例代码,演示如何对一个包含数组、英文、符号的集合进行自定义排序: ```java import java.util.Comparator; public class MyComparator implements Comparator<String> { @Override public int compare(String s1, String s2) { // 首先判断排序的内容属于哪种类型 boolean s1IsArray = s1.startsWith("["); boolean s2IsArray = s2.startsWith("["); if (s1IsArray && s2IsArray) { // 如果都是数组,按数组长度排序 int len1 = s1.length() - s1.replace(",", "").length() + 1; int len2 = s2.length() - s2.replace(",", "").length() + 1; return Integer.compare(len1, len2); } else if (s1IsArray) { // 如果只有s1是数组,排在后面 return 1; } else if (s2IsArray) { // 如果只有s2是数组,排在前面 return -1; } else { // 如果都不是数组,按字母排序 return s1.compareTo(s2); } } } ``` 使用示例: ```java import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("b"); list.add("[1,2,3]"); list.add("d"); list.add("a"); list.add("[4,5]"); list.add("c"); Collections.sort(list, new MyComparator()); System.out.println(list); // [a, b, c, [4,5], [1,2,3], d] } } ``` 在上面的示例中,我们定义了一个MyComparator类来实现自定义排序,然后使用Collections.sort方法对集合进行排序。最终的排序结果是:a、b、c、[4,5]、[1,2,3]、d。可以看到,按字母排序英文排在前面,按数组长度排序的数组排在后面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值