字符串比较 - 前缀

时间:2015-01-07 11:17:40

标签: java sorting collections

我有一个字符串列表,它基本上是从某些仪器读取的负整数或正整数,例如-12.4SEC, -13.5SEC, 14.12SEC等我要排序,当我使用compareTo()字符串类的方法时,它按字典顺序排序。但我希望它按整数排序 我的输出应为-13.5SEC, -12.4SEC, 14.12SEC etc.

但我得到的输出是-12.4SEC, -13.5SEC, 14.12SEC

3 个答案:

答案 0 :(得分:3)

如果后缀(SEC thingy)在任何地方都相同,那么最好的选择就是将列表转换为双精度数,并对其进行排序。如果你使用的是java 8,你可能会看起来很优雅:

input
   .stream
   .map(s -> Double.valueOf(s.replaceAll("SEC$", "")))
   .collect(Collectors.toList)
   .sort

在java 7中你必须强制执行它,但想法是一样的:创建一个新列表,并向其中添加元素,剥离后缀,并解析为Double as你去,然后排序双打。

如果必须保留后缀,则会使事情变得复杂一些。一种可能性是创建一个具有原始字符串和解析后的double的中间对象,并将其用于排序:

private static class Wrapper implements Comparable<Wrapper> {
    String original;
    double parsed;
    public Wrapper(String original) {
        parsed = Double.parseDouble(original.replaceAll("\\D+$", ""));
        this.original = original;
    }
    public int compareTo(Wrapper other) {
        if (this.parsed == other.parsed) return 0;
        else return this.parsed < other.parsed ? -1 : 1;
    }
}

现在,与上述类似:

input
    .stream
    .map(s -> Wrapper(s))
    .sorted
    .map(w -> w.original)
    .collect(Collectors.toList)

答案 1 :(得分:0)

您可以创建自己的Comparator忽略"SEC"部分,并将其余部分视为Double

public class SECComparator implements Comparator<String> {
    private static String removeSEC(String s) {
        return s.replace("SEC", "");
    }

    @Override    
    public int compare(String s1, String s2) {
        Double d1 = Double.valueOf(removeSEC(s1));
        Double d2 = Double.valueOf(removeSEC(s2));
        return d1.compareTo(d2);
    }
}

答案 2 :(得分:-2)

您可以编写一个自定义比较器,根据字符串中第一个遇到的double值对字符串进行排序(这是@musefan建议的比较器)

public class DoubleComparator implements Comparator<String> {
    private double parseDouble(String string) {
        Pattern pattern = Pattern.compile("-?[0-9]+?(.[0-9]*)");
        Matcher m = pattern.matcher(string);

        if (m.find())
            return Double.parseDouble(m.group());
        else
            throw new IllegalStateException();
    }

    @Override
    public int compare(String o1, String o2) {
        double d1 = parseDouble(o1);
        double d2 = parseDouble(o2);

        if (d1 < d2)
            return -1;
        else if (d1 > d2)
            return 1;
        else
            return 0;
    }
}

测试代码:

String[] strings = new String[] { "-12.4SEC", "-13.5SEC", "14.12SEC", "-100SEC" };

Arrays.sort(strings, new DoubleComparator());

for (String string : strings)
    System.out.println(string);

输出:

-100SEC
-13.5SEC
-12.4SEC
14.12SEC