【问题标题】:how to sort a collection which has strings, integers and alphanumerics in java如何在java中对包含字符串、整数和字母数字的集合进行排序
【发布时间】:2011-09-27 10:27:28
【问题描述】:

有一些值,例如 AB、A012B、CD、1、10、01、9 我必须对它们进行排序 输出应该是 01,1,9,10,A012B,AB,CD 可以使用任何集合 我正在尝试使用 collection.sort 功能 但它认为一切都是字符串 和打印像 01,1,10,9,A012B,AB,CD 这不是我的要求...请帮助

【问题讨论】:

    标签: java sorting collections


    【解决方案1】:

    //钓鱼技巧

    List<String> values = new ArrayList<String>();
        values.add("AB");
        values.add("A012B");
        values.add("CD");
        values.add("1");
        values.add("10");
        values.add("01");
        values.add("9");
        values.add("I");
        Collections.sort(values, new Comparator<String>() {
    
            @Override
            public int compare(String o1, String o2) {
                // TODO tweak the comparator here 
                try{
                Integer integer1 = Integer.valueOf(o1);
                Integer integer2 = Integer.valueOf(o2);
                return integer1.compareTo(integer2);
                }catch (java.lang.NumberFormatException e) {
                    return o1.compareTo(o2);
                }
            }
        });
        System.out.println(values);
    }
    

    //还不够???

    //这是鱼

    public static void main(String[] args) throws Exception {
        List<String> values = new ArrayList<String>();
        values.add("AB");
        values.add("A012B");
        values.add("CD");
        values.add("1");
        values.add("10");
        values.add("01");
        values.add("9");
    
        int maxLen = 0;
        for (String string : values) {
            if (string.length() > maxLen) {
                maxLen = string.length();
            }
        }
    
        Collections.sort(values, new MyComparator(maxLen));
    
        System.out.println(values);
    }
    
    public static class MyComparator implements Comparator<String> {
        private int maxLen;
        private static final String REGEX = "[0-9]+";
    
        public MyComparator(int maxLen) {
            this.maxLen = maxLen;
    
        }
    
        @Override
        public int compare(String obj1, String obj2) {
            String o1 = obj1;
            String o2 = obj2;
            // both numbers
            if (o1.matches("[1-9]+") && o2.matches("[1-9]+")) {
                Integer integer1 = Integer.valueOf(o1);
                Integer integer2 = Integer.valueOf(o2);
                return integer1.compareTo(integer2);
            }
    
            // both string
            if (o1.matches("[a-zA-Z]+") && o2.matches("[a-zA-Z]+")) {
                return o1.compareTo(o2);
            }
    
            Pattern p = Pattern.compile(REGEX);
            Matcher m1 = p.matcher(o1);
            Matcher m2 = p.matcher(o2);
    
            List<String> list = new ArrayList<String>();
            while (m1.find()) {
                list.add(m1.group());
            }
            for (String string : list) {
                o1.replaceFirst(string, leftPad(string, "0", maxLen));
            }
    
            list.clear();
    
            while (m2.find()) {
                list.add(m2.group());
            }
            for (String string : list) {
                o2.replaceFirst(string, leftPad(string, "0", maxLen));
            }
            return o1.compareTo(o2);
    
        }
    }
    
    public static String leftPad(String stringToPad, String padder, Integer size) {
    
        final StringBuilder strb = new StringBuilder(size.intValue());
        final StringCharacterIterator sci = new StringCharacterIterator(padder);
    
        while (strb.length() < (size.intValue() - stringToPad.length())) {
            for (char ch = sci.first(); ch != CharacterIterator.DONE; ch = sci.next()) {
                if (strb.length() < (size.intValue() - stringToPad.length())) {
                    strb.insert(strb.length(), String.valueOf(ch));
                }
            }
        }
    
        return strb.append(stringToPad).toString();
    }
    

    【讨论】:

    • 我想,一切都很好,除了,我想要“01”在“1”之前。关于我们如何实现这一目标的任何想法???输出为 1,01,9,A01B,AB,CD
    • 非常感谢.. 非常感谢您的努力
    • 首先,很棒的代码。一个例外...10 应该在 9 之后而不是。例如,list={2,10,1,21,9} 应该输出为 1,2,9,10,21 但输出为 1,10,2,21,9 你能更新答案来修复它吗?请:)
    【解决方案2】:

    你应该实现一个比较器:

    给定对象 O1 和对象 O2:

    您首先尝试将它们转换为数字并比较数字。

    如果 O1 是数字而 O2 不是,则认为 O2 大于 O1

    如果 O1 不是数字而 O2 是数字,则认为 O1 大于 O1

    如果两者都不是数字,则将它们作为字符串进行比较。

    【讨论】:

      【解决方案3】:

      你必须实现比较器。我假设你所有的数据都是字符串的形式。因此,默认情况下 "10" 在 "9" 之前。你需要自己实现 java.util.Comparator 来解决这个问题。

      【讨论】:

        【解决方案4】:

        首先您编写自己的Comparator,然后调用Collections.sort(List, Comparator)

        【讨论】:

          【解决方案5】:

          User952887 的答案很好,除了它仍然给出 0,01,1,10,11,2,21,3,4,5,...等(注意 10 在 1 之后和 2 之前)。查看以下链接以获取一个很棒的字母数字比较器,它将返回 0,1,2,3,4,5,10,11,21 http://sanjaal.com/java/tag/sample-alphanumeric-sorting/ 唯一的问题是它将返回 0,1,01-User952887 已修复.

          【讨论】:

            猜你喜欢
            • 2019-03-28
            • 2016-10-28
            • 1970-01-01
            • 2023-03-10
            • 2022-11-23
            • 1970-01-01
            • 2021-02-22
            • 2011-02-01
            相关资源
            最近更新 更多