Flite
Flite

Reputation: 59

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 :

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"). 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();
        }
    }
}

Upvotes: 1

Views: 100

Answers (1)

Elliott Frisch
Elliott Frisch

Reputation: 201439

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. 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]

Upvotes: 3

Related Questions