是否可以更改某些符号的优先级(权重)?

时间:2018-11-05 08:11:24

标签: java string gwt compare comparator

我想为字符串值创建一个比较器,但是根据https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html,下划线符号的值大于任何数字。可以以某种方式更改它吗?

2 个答案:

答案 0 :(得分:2)

简短答案

是的。您需要一个自定义的字符串比较器。

解决方案

假设您需要对字符串列表进行排序:

[a_123, ab123, a123, 123, _123]

如果您使用Collections.sort对其进行排序,则它将按以下顺序进行排序:

[123, _123, a123, a_123, ab123]

但是您想覆盖_的“权重”。为此,您需要一个自定义的字符串比较器。让我们复制并修改一下java.lang.String#compareTo

private int customStringComparator(String s1, String s2) {
    int len1 = s1.length();
    int len2 = s2.length();
    int lim = Math.min(len1, len2);
    char v1[] = s1.toCharArray();
    char v2[] = s2.toCharArray();

    int k = 0;
    while (k < lim) {
        char c1 = v1[k];
        char c2 = v2[k];
        // You can add your custom comparison here:
        if ('_' == c1 && Character.isDigit(c2)) {
            // We intentionally return inverted result
            return c2  - c1;
        }else if(c1 != c2) {
            return c1 - c2;
        }
        k++;
    }
    return len1 - len2;
}

现在我们可以将customStringComparator传递给Collections.sort

Collections.sort(list, this::customStringComparator);

列表将按以下顺序排序:

[_123, 123, a_123, a123, ab123]

如您所见,现在_在数字之前。

答案 1 :(得分:0)

这可能有效:

private int compareStrings(String o1, String o2) {
    if(o1.matches("\\d+") && o2.equals("_")) {
        return 1;
    }
    if(o1.equals("_") && o2.matches("\\d+")) {
        return -1;
    }
    return o1.compareTo(o2);
}

然后像这样定义您的比较器:

Comparator<String> stringComparator2 = this::compareStrings;

编辑:

根据中间的_字符串不起作用的情况,如何将ASCII表中的_替换为之前的字符(例如" "):

public static int compareStrings(String o1, String o2) {
    o1 = o1.replaceAll("_", " ");
    o2 = o2.replaceAll("_", " ");
    return o1.compareTo(o2);
}