简体   繁体   English

如何按字母顺序对文件进行排序?

[英]How to sort a file in alphabetical order?

I'm currently trying to make a program in java to sort a content of a file in alphabetical order, the file contains :我目前正在尝试在 java 中制作一个程序来按字母顺序对文件的内容进行排序,该文件包含:

camera10:192.168.112.43
camera12:192.168.2.112
camera1:127.0.0.1    
camera2:133.192.31.42    
camera3:145.154.42.58    
camera8:192.168.12.205    
camera3:192.168.2.122    
camera5:192.168.112.54    
camera123:192.168.2.112    
camera4:192.168.112.1    
camera6:192.168.112.234    
camera7:192.168.112.20    
camera9:192.168.2.112

And I would like to sort them and write that back into the file (which in this case is "daftarCamera.txt").我想对它们进行排序并将其写回文件(在本例中为“daftarCamera.txt”)。 But somehow my algorithm sort them in the wrong way, which the result is :但不知何故,我的算法以错误的方式对它们进行排序,结果是:

camera10:192.168.112.43    
camera123:192.168.2.112    
camera12:192.168.2.112    
camera1:127.0.0.1    
camera2:133.192.31.42    
camera3:145.154.42.58    
camera3:192.168.2.122    
camera4:192.168.112.1    
camera5:192.168.112.54    
camera6:192.168.112.234    
camera7:192.168.112.20    
camera8:192.168.12.205    
camera9:192.168.2.112

while the result I want is :而我想要的结果是:

camera1:127.0.0.1
camera2:133.192.31.42
camera3:145.154.42.58
camera3:192.168.2.122
camera4:192.168.112.1
camera5:192.168.112.54
camera6:192.168.112.234
camera7:192.168.112.20
camera8:192.168.12.205
camera9:192.168.2.112
camera10:192.168.112.43
camera12:192.168.2.112
camera123:192.168.2.112

Here's the code I use :这是我使用的代码:

public void sortCamera() {
    BufferedReader reader = null;
    BufferedWriter writer = null;

    ArrayList <String> lines = new ArrayList<String>();

    try {
        reader = new BufferedReader(new FileReader (log));
        String currentLine = reader.readLine();
        while (currentLine != null){
            lines.add(currentLine);
            currentLine = reader.readLine();
        }
        Collections.sort(lines);

        writer = new BufferedWriter(new FileWriter(log));
        for (String line : lines) {
            writer.write(line);
            writer.newLine();
        }
    } catch(IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (reader != null) {
                reader.close();
            }
            if(writer != null){
                writer.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

You are currently performing a lexical sort, to perform a numerical sort you would need a Comparator that sorts the lines numerically on the value between "camera" and : in each line.您当前正在执行词法排序,要执行数字排序,您需要一个Comparator对每一行中"camera":之间的值进行数字排序。 You could split by : , and then use a regular expression to grab the digits, parse them and then compare.您可以按:分割,然后使用正则表达式获取数字,解析它们然后进行比较。 Like,喜欢,

Collections.sort(lines, (String a, String b) -> {
    String[] leftTokens = a.split(":"), rightTokens = b.split(":");
    Pattern p = Pattern.compile("camera(\\d+)");
    int left = Integer.parseInt(p.matcher(leftTokens[0]).replaceAll("$1"));
    int right = Integer.parseInt(p.matcher(rightTokens[0]).replaceAll("$1"));
    return Integer.compare(left, right);
});

Making a fully reproducible example制作一个完全可重现的示例

List<String> lines = new ArrayList<>(Arrays.asList( //
        "camera10:192.168.112.43", //
        "camera12:192.168.2.112", //
        "camera1:127.0.0.1", //
        "camera2:133.192.31.42", //
        "camera3:145.154.42.58", //
        "camera8:192.168.12.205", //
        "camera3:192.168.2.122", //
        "camera5:192.168.112.54", //
        "camera123:192.168.2.112", //
        "camera4:192.168.112.1", //
        "camera6:192.168.112.234", //
        "camera7:192.168.112.20", //
        "camera9:192.168.2.112"));
Collections.sort(lines, (String a, String b) -> {
    String[] leftTokens = a.split(":"), rightTokens = b.split(":");
    Pattern p = Pattern.compile("camera(\\d+)");
    int left = Integer.parseInt(p.matcher(leftTokens[0]).replaceAll("$1"));
    int right = Integer.parseInt(p.matcher(rightTokens[0]).replaceAll("$1"));
    return Integer.compare(left, right);
});
System.out.println(lines);

And that outputs那输出

[camera1:127.0.0.1, camera2:133.192.31.42, camera3:145.154.42.58, camera3:192.168.2.122, camera4:192.168.112.1, camera5:192.168.112.54, camera6:192.168.112.234, camera7:192.168.112.20, camera8:192.168.12.205, camera9:192.168.2.112, camera10:192.168.112.43, camera12:192.168.2.112, camera123:192.168.2.112]

Your sorting algorithm assumes the ordinary collating sequence, ie sorts the strings by alphabetical order, as if the digits were letters.您的排序算法采用普通的整理顺序,即按字母顺序对字符串进行排序,就好像数字是字母一样。 Hence the shorter string come first.因此较短的字符串首先出现。

You need to specify an ad-hoc comparison function that splits the string and extracts the numerical value of the suffix.您需要指定一个临时比较函数,用于拆分字符串并提取后缀的数值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM