Java - 对具有双精度值的字母数字列表进行排序

Java - sorting an alphanumerical list with double values

我在对包含字母、整数和双精度值的字母数字列表进行排序时遇到问题。到处寻找答案,但他们对我的情况无能为力,因为我的列表会以错误的方式排序,所以我请求你的帮助。 考虑有一个字符串列表:[-2.2, 2.2, 2.2, -22, -22, -22, -1.1, qqqq]。我的目标是让这个列表按升序排序,字母排在后面。 Collections.sort() 方法为我提供了以下排序列表:[-1.1, -2.2, -22, -22, -22, 2.2, 2.2, qqqq] 这与我正在寻找的相去甚远。我还尝试了来自 Whosebug 的以下示例:

    public class ComparatorClass{
    final Pattern p = Pattern.compile("^\d+");
    String[] examples = {"-2.2", "2.2", "2.2", "-22", "-22", "-22", "-1.1", "qqqq"};

    public void go() {
        Comparator<String> c = new Comparator<String>() {
            @Override
            public int compare(String object1, String object2) {
                Matcher m = p.matcher(object1);
                Double number1 = null;
                if (!m.find()) {
                    return object1.compareTo(object2);
                } else {
                    Double number2 = null;
                    number1 = Double.parseDouble(m.group());
                    m = p.matcher(object2);
                    if (!m.find()) {
                        return object1.compareTo(object2);
                    } else {
                        number2 = Double.parseDouble(m.group());
                        int comparison = number1.compareTo(number2);
                        if (comparison != 0) {
                            return comparison;
                        } else {
                            return object1.compareTo(object2);
                        }
                    }
                }
            }
        };
        List<String> examplesList = new ArrayList<>(Arrays.asList(examples));

        Collections.sort(examplesList, c);
        System.out.println(examplesList);
    }
}

可悲的是,这个也给了我与 Collections.sort() 方法相同的答案。我需要 [-22, -22, -22, -2.2, -1.1, 2.2, 2.2, qqqq] 的答案。 任何帮助表示赞赏。

我建议使用一种策略,将文本比较和数字比较分开。这使得逻辑不那么混乱。对于混合情况,即要比较的字符串一个是文本,另一个是数字,逻辑清楚如何排序。

Comparator<String> c = new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        boolean b1 = s1.matches(".*[^0-9.\-].*");
        boolean b2 = s2.matches(".*[^0-9.\-].*");

        // if both are bona fide doubles
        if (!b1 && !b2) {
            Double d1 = Double.parseDouble(s1);
            Double d2 = Double.parseDouble(s2);

            return d1.compareTo(d2);
        }
        // if both are text, then compare as strings
        else if (b1 && b2) {
            return s1.compareTo(s2);
        }
        // otherwise return one or the other, depending on which is text/number
        else return b2 ? -1 : 1;
    }
};