java排序混乱的字符串字母和数字排序,解决11在2前面排序

有个需求,字符串中有很多数字,需要按照最后的数字排序,使用Java原生排序发现11会排在2前面,呈现是XXXX1,XXXX11,XXXX2这样,于是找了找解决方案,记录一下

/**
 * @Version 1.0
 * @Author:zly
 * @Date:2023/4/18
 * @Content: java排序混乱的字符串字母和数字排序,解决11在2前面
 */
public class NaturalOrderComparator implements Comparator {


    int compareRight(String a, String b) {
        int bias = 0;
        int ia = 0;
        int ib = 0;

        // The longest run of digits wins. That aside, the greatest
        // value wins, but we can't know that it will until we've scanned
        // both numbers to know that they have the same magnitude, so we
        // remember it in BIAS.
        for (; ; ia++, ib++) {
            char ca = charAt(a, ia);
            char cb = charAt(b, ib);

            if (!Character.isDigit(ca) && !Character.isDigit(cb)) {
                return bias;
            } else if (!Character.isDigit(ca)) {
                return -1;
            } else if (!Character.isDigit(cb)) {
                return +1;
            } else if (ca < cb) {
                if (bias == 0) {
                    bias = -1;
                }
            } else if (ca > cb) {
                if (bias == 0)
                    bias = +1;
            } else if (ca == 0 && cb == 0) {
                return bias;
            }
        }
    }

    public int compare(Object o1, Object o2) {
        String a = o1.toString();
        String b = o2.toString();

        int ia = 0, ib = 0;
        int nza = 0, nzb = 0;
        char ca, cb;
        int result;

        while (true) {
            // only count the number of zeroes leading the last number compared
            nza = nzb = 0;

            ca = charAt(a, ia);
            cb = charAt(b, ib);

            // skip over leading spaces or zeros
            while (Character.isSpaceChar(ca) || ca == '0') {
                if (ca == '0') {
                    nza++;
                } else {
                    // only count consecutive zeroes
                    nza = 0;
                }

                ca = charAt(a, ++ia);
            }

            while (Character.isSpaceChar(cb) || cb == '0') {
                if (cb == '0') {
                    nzb++;
                } else {
                    // only count consecutive zeroes
                    nzb = 0;
                }

                cb = charAt(b, ++ib);
            }

            // process run of digits
            if (Character.isDigit(ca) && Character.isDigit(cb)) {
                if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) {
                    return result;
                }
            }

            if (ca == 0 && cb == 0) {
                // The strings compare the same. Perhaps the caller
                // will want to call strcmp to break the tie.
                return nza - nzb;
            }

            if (ca < cb) {
                return -1;
            } else if (ca > cb) {
                return +1;
            }

            ++ia;
            ++ib;
        }
    }

    static char charAt(String s, int i) {
        if (i >= s.length()) {
            return 0;
        } else {
            return s.charAt(i);
        }
    }


    public static void main(String[] args) {
        String[] strings = new String[]{"zzdvlp_test__007-zzdvlp_test__008/75-1",
                "zzdvlp_test__007-zzdvlp_test__008/75-11",
                "zzdvlp_test__007-zzdvlp_test__008/75-2"};

        List orig = Arrays.asList(strings);

        System.out.println("Original: " + orig);

        List scrambled = Arrays.asList(strings);
        Collections.shuffle(scrambled);

        System.out.println("Scrambled: " + scrambled);

        Collections.sort(scrambled, new NaturalOrderComparator());

        System.out.println("Sorted: " + scrambled);
    }

运行结果为

Original: [zzdvlp_test__007-zzdvlp_test__008/75-1, zzdvlp_test__007-zzdvlp_test__008/75-11, zzdvlp_test__007-zzdvlp_test__008/75-2]
Scrambled: [zzdvlp_test__007-zzdvlp_test__008/75-11, zzdvlp_test__007-zzdvlp_test__008/75-1, zzdvlp_test__007-zzdvlp_test__008/75-2]
Sorted: [zzdvlp_test__007-zzdvlp_test__008/75-1, zzdvlp_test__007-zzdvlp_test__008/75-2, zzdvlp_test__007-zzdvlp_test__008/75-11]

OK,符合要求

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Java中的`Comparator`接口自定义排序规则来实现字符串按照字母数字排序。具体步骤如下: 1. 定义一个实现了`Comparator`接口的类,重写`compare`方法。 2. 在`compare`方法中,对两个字符串进行比较,返回比较结果。 1. 如果两个字符串在相同位置上的字符相同,继续比较下一个字符; 2. 如果两个字符串在相同位置上的字符不同,按照字符的ASCII码大小进行比较,ASCII码小的排在前面; 3. 如果一个字符串的某个位置上没有字符,认为它的字符比另一个字符串的相应位置上的字符小,排在前面。 以下是示例代码: ```java import java.util.Arrays; import java.util.Comparator; public class StringSort { public static void main(String[] args) { String[] arr = {"a123", "c", "b", "123", "A", "B", "c123"}; Arrays.sort(arr, new MyComparator()); System.out.println(Arrays.toString(arr)); } } class MyComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { int i = 0, j = 0; while (i < o1.length() && j < o2.length()) { char c1 = o1.charAt(i), c2 = o2.charAt(j); if (c1 == c2) { i++; j++; } else if (Character.isDigit(c1) && Character.isDigit(c2)) { int num1 = 0, num2 = 0; while (i < o1.length() && Character.isDigit(o1.charAt(i))) { num1 = num1 * 10 + o1.charAt(i) - '0'; i++; } while (j < o2.length() && Character.isDigit(o2.charAt(j))) { num2 = num2 * 10 + o2.charAt(j) - '0'; j++; } if (num1 != num2) { return num1 - num2; } } else { return c1 - c2; } } return o1.length() - o2.length(); } } ``` 运行结果为: ``` [A, B, a123, b, c, c123, 123] ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值