Java 如何对字母数字字符串排序

Java 如何对字母数字字符串排序,java,sorting,Java,Sorting,我对包含整数的字符串排序有问题。如果我使用以下代码,我会得到如下排序: 1一些,2一些,20一些,21一些,3一些,一些 但我希望它的排序如下: 1一些,2一些,3一些,20一些,21一些,一些 我该怎么做 谢谢 Collections.sort(selectedNodes, new Comparator<DefaultMutableTreeNode>() { @Override public int compare(DefaultMutableTreeNod

我对包含整数的字符串排序有问题。如果我使用以下代码,我会得到如下排序: 1一些,2一些,20一些,21一些,3一些,一些

但我希望它的排序如下: 1一些,2一些,3一些,20一些,21一些,一些

我该怎么做

谢谢

Collections.sort(selectedNodes,
    new Comparator<DefaultMutableTreeNode>() {
    @Override
    public int compare(DefaultMutableTreeNode o1,
        DefaultMutableTreeNode o2) {
        return o1.getUserObject().toString()
            .compareTo(o2.getUserObject().toString());
    }
    });
Collections.sort(selectedNodes,
新比较器(){
@凌驾
公共int比较(默认可变树节点o1,
DefaultMutableTreeNode o2){
返回o1.getUserObject().toString()
.compareTo(o2.getUserObject().toString());
}
});

您的解决方案在于,您可以像这样实现您需要实现自己的
比较器来进行这种自定义排序。默认的
String.compareTo()
方法似乎将数字排序在字符之前。当将
20some
中的
0
3some中的
s
进行比较时,
0
具有更高的排序优先级,因此整个单词首先排序。
您需要做的是:尝试将字符串拆分为数字和字符部分。这是一项艰巨的任务,因为那些
String
s可以由许多这些部分组成(或者不是吗?)。您可以使用Murtaza已经向您展示的算法,如
Alphanum

如果您想自己实现它,您可以检查数字部分的结束位置。然后用
Integer.parse()将其解析为
int
。比较
int
两个
字符串中的部分,然后比较其余部分。嗯,这可能不是最专业的解决方案,但作为初学者,你可能希望自己动手制作这些东西来学习它。

String[]str=newstring[]{“1some”、“2some”、“20some”、“21some”、“3some”、“some”};
    String [] str = new String[]{"1some", "2some", "20some", "21some", "3some", "some"};
    List<String> list = Arrays.asList(str);

    Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
    System.out.println(list);
List=Arrays.asList(str); Collections.sort(列表、字符串、不区分大小写的顺序); 系统输出打印项次(列表);
下面是一个关于如何实现这一点的自包含示例(未特别优化):

解释

  • 该示例使用常量
    模式
    推断数字是否位于
    字符串的起始位置
  • 如果第一个
    字符串中不存在,则会将其与第二个字符串进行比较
  • 如果第一个中确实存在,则检查第二个
  • 如果第二个字符串中不存在,它将再次按原样比较两个
    字符串
  • 如果两者都存在,它会比较
    整数
    s,而不是整个
    字符串
    s,因此会产生数值比较,而不是词典比较
  • 如果数字比较相同,则返回到整个
    字符串的字典比较(感谢您发现这一个)

您不能使用默认字符串compareTo(),而是需要按照以下算法比较字符串

  • 逐个字符循环遍历第一个和第二个字符串,并获取所有字符串或数字的块
  • 检查块是数字还是字符串
  • 如果数字按数字排序,则使用字符串compareTo()

  • 重复这些步骤。

    首先制作一个字母数字比较器,将字符串拆分为字符串或整数部分

    public class AlphaNumericalComparator implements Comparator<String> {
        @Override
        public int compare(String o1, String o2) {
            List<Object> parts1 = partsOf(o1);
            List<Object> parts2 = partsOf(o2);
            while (!parts1.isEmpty() && !parts2.isEmpty()) {
                Object part1 = parts1.remove(0);
                Object part2 = parts2.remove(0);
                int cmp = 0;
                if (part1 instanceof Integer && part2 instanceof Integer) {
                    cmp = Integer.compare((Integer)part1, (Integer)part2);
                } else if (part1 instanceof String && part2 instanceof String) {
                    cmp = ((String) part1).compareTo((String) part2);
                } else {
                    cmp = part1 instanceof String ? 1 : -1; // XXXa > XXX1
                }
                if (cmp != 0) {
                    return cmp;
                }
            }
            if (parts1.isEmpty() && parts2.isEmpty()) {
                return 0;
            }
            return parts1.isEmpty() ? -1 : 1;
        }
    
        private List<Object> partsOf(String s) {
            List<Object> parts = new LinkedList<>();
            int pos0 = 0;
            int pos = 0;
            boolean wasDigit = false;
            while (true) {
                if (pos >= s.length()
                        || Character.isDigit(s.charAt(pos)) != wasDigit) {
                    if (pos > pos0) {
                        String part = s.substring(pos0, pos);
                        parts.add(wasDigit? Integer.valueOf(part) : part);
                        pos0 = pos;
                    }
                    if (pos >= s.length()) {
                        break;
                    }
                    wasDigit = !wasDigit;
                }
                ++pos;
            }
            return parts;
        }
    };
    
    public类AlphaNumericalComparator实现比较器{
    @凌驾
    公共整数比较(字符串o1、字符串o2){
    列表零件1=零件f(o1);
    列表零件2=零件SOF(o2);
    而(!parts1.isEmpty()&&!parts2.isEmpty()){
    对象part1=parts1.删除(0);
    对象part2=parts2.删除(0);
    int-cmp=0;
    if(第1部分整数实例和第2部分整数实例){
    cmp=整数。比较((整数)第1部分,(整数)第2部分);
    }else if(第1部分字符串实例和第2部分字符串实例){
    cmp=((字符串)第1部分)。与((字符串)第2部分进行比较;
    }否则{
    cmp=字符串的第1部分实例?1:-1;//XXXa>XXX1
    }
    如果(cmp!=0){
    返回cmp;
    }
    }
    if(parts1.isEmpty()&&parts2.isEmpty()){
    返回0;
    }
    返回部分1.isEmpty()?-1:1;
    }
    私有列表部分(字符串s){
    列表部分=新建链接列表();
    int pos0=0;
    int pos=0;
    布尔数字=假;
    while(true){
    如果(位置>=s.长度()
    ||Character.isDigit(s.charAt(pos))!=wasDigit){
    如果(位置>位置0){
    字符串部分=s.子字符串(位置0,位置);
    parts.add(wasDigit?Integer.valueOf(part):part);
    pos0=pos;
    }
    如果(位置>=s.长度()){
    打破
    }
    wasDigit=!wasDigit;
    }
    ++pos;
    }
    返回部件;
    }
    };
    

    然后在您自己的比较器中使用此比较器,在Java 8中,您可以简单地使用比较器的静态方法。

    您可以在一行中使用正则表达式提取数字部分:

    Collections.sort(selectedNodes, new Comparator<DefaultMutableTreeNode>() {
        @Override
        public int compare(DefaultMutableTreeNode o1,
            DefaultMutableTreeNode o2) {
            return Integer.parseInt(o1.getUserObject().toString().replaceAll("\\D", "")) -
                Integer.parseInt(o2.getUserObject().toString().replaceAll("\\D", ""));
        }
    });
    
    Collections.sort(selectedNodes,new Comparator(){
    @凌驾
    公共int比较(默认可变树节点o1,
    DefaultMutableTreeNode o2){
    返回Integer.parseInt(o1.getUserObject().toString().replaceAll(“\\D”,”))-
    Integer.parseInt(o2.getUserObject().toString().replaceAll(“\\D”,是“”);
    }
    });
    
    这是一个使用Java的有效解决方案。如果您对代码有任何建议,请随时告诉我


    如果您知道模式始终为NUMALPHA或ALPHANUM,则alpha始终相同:

    if(str1.length() != str2.length()){
       return str1.length() - str2.length();
    }
    
    return str1.compareTo(str2);
    

    如果您有字母数字字符串数组,您可以使用

    Arrays.sort(Array_name)
    
    及 然后打印:

    for(String a : Array_name)
        System.out.print(a);
    
    如何在Java中使用 比较器

    import java.util.ArrayList;
    导入java.util.array;
    导入java.util.Collections;
    导入java.util.Comparator;
    导入java.util.Li
    
    [1some, 2some, 20some, 21some, 3some, some, 1abc, abc]
    [1abc, 1some, 2some, 3some, 20some, 21some, abc, some]
    
    if(str1.length() != str2.length()){
       return str1.length() - str2.length();
    }
    
    return str1.compareTo(str2);
    
    Arrays.sort(Array_name)
    
    for(String a : Array_name)
        System.out.print(a);
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class AlphaNumericSorting {
        public static void main(String[] args) {
            final Pattern p = Pattern.compile("^\\d+");
            String[] examples = { "CD", "DE", "0A", "0B", "0C", "12", "0K", "TA", "0D", "01", "02", "11", "AB", "MN" };
            Comparator<String> c = new Comparator<String>() {
                @Override
                public int compare(String object1, String object2) {
                    Matcher m = p.matcher(object1);
                    Integer number1 = null;
                    if (!m.find()) {
                        Matcher m1 = p.matcher(object2);
                        if (m1.find()) {
                            return object2.compareTo(object1);
                        } else {
                            return object1.compareTo(object2);
                        }
                    } else {
                        Integer number2 = null;
                        number1 = Integer.parseInt(m.group());
                        m = p.matcher(object2);
                        if (!m.find()) {
                            // return object1.compareTo(object2);
                            Matcher m1 = p.matcher(object1);
                            if (m1.find()) {
                                return object2.compareTo(object1);
                            } else {
                                return object1.compareTo(object2);
                            }
                        } else {
                            number2 = Integer.parseInt(m.group());
                            int comparison = number1.compareTo(number2);
                            if (comparison != 0) {
                                return comparison;
                            } else {
                                return object1.compareTo(object2);
                            }
                        }
                    }
                }
            };
            List<String> examplesList = new ArrayList<String>(Arrays.asList(examples));
            Collections.sort(examplesList, c);
            System.out.println(examplesList);
        }
    }