How to sort Alphanumeric String

前端 未结 11 1434
我寻月下人不归
我寻月下人不归 2020-12-10 06:25

I have a problem with sorting strings which include integers. If I use the below code I get sorting like: 1some, 2some, 20some, 21some, 3some, some

However I want it

11条回答
  •  温柔的废话
    2020-12-10 07:00

    First make an alphanumerical comparator splitting the string in String or Integer parts.

    public class AlphaNumericalComparator implements Comparator {
        @Override
        public int compare(String o1, String o2) {
            List parts1 = partsOf(o1);
            List 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 partsOf(String s) {
            List 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;
        }
    };
    
    
    

    Then use this comparator in your own one, in Java 8 you may simply use Comparator's static methods.

    提交回复
    热议问题