Java - 使用双值

时间:2018-04-17 10:59:53

标签: sorting double comparator alphanumeric

我在排序字母数字列表时遇到问题,该列表包含字母,整数和双精度值。到处寻找答案,但他们无法帮助我,因为我的清单会以错误的方式排序,所以我要求你的帮助。 考虑有一个字符串列表:[ - 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],这远远不是我想要的。我还尝试了stackoverflow中的以下示例:

    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]。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

我建议使用一种策略,分别隔离文本和数字比较。这使逻辑更容易混淆。对于混合情况,即一个要比较的字符串是文本,另一个字符串是数字,逻辑清楚如何排序。

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;
    }
};