Ordering a File from highest number to lowest, retaining the other information

Viewed 62

I'm looking for a way to be able to read a file and rewrite the same file but taking into account all the information inside it to order it from highest to lowest

/*Scores*/
    Mathew: 540
    Stacy: 070
    Andre: 761
    Alfred: 340

So that would be how it's written in my .txt file and I want it to be:

/*Scores*/
Andre: 761
Mathew: 540
Alfred: 340
Stacy: 070

I'm writing the file for each level, the following way:

public void scoreWrite(int levelID) throws IOException {
    File Highscores = new File("Scoreboard/Level_" + levelID + "_Highscore.txt");
    //      Level_0_Highscore.txt

    if(Highscores.createNewFile()) {
        FileWriter highscoreWriter = new FileWriter(Highscores, false);
        highscoreWriter.write("/*---Highscores---*/ \n \n");
        highscoreWriter.write(SokobanGame.getInstance().getPlayerName()+ "'s " + "score: " + getScore() + " points;\n");
        highscoreWriter.close();
    }else {
        Highscores = new File("Scoreboard/Level_" + levelID + "_Highscore.txt");
        FileWriter highscoreWriter = new FileWriter(Highscores, true);
        highscoreWriter.write(SokobanGame.getInstance().getPlayerName()+ "'s " + "score: " + getScore() + " points;\n");
        highscoreWriter.close();
    }
}

But now for the way to order, I'm at a complete loss... Any help would be appreciated!

2 Answers

You can simplify it using a SortedMap. First create a SortedMap:

SortedMap<Integer, String> map = new TreeMap<>();
map.put(540, "Mathew");
map.put(070, "Stacy");

Now in the method:

File Highscores = new File("Scoreboard/Level_" + levelID + "_Highscore.txt");

String save = map.entrySet().stream() // stream over map
        .map(s -> s.getValue() + ": " + s.getKey()) // map to required format
        .collect(Collectors.joining("\n")); // join the elements

Files.writeString(Highscores.toPath(), save);

Here is how you can do it by reading from one file and writing to another:

Path path = Paths.get("Scoreboard/Level_" + levelID + "_Highscore.txt");

String save = Files.readAllLines(path).stream() // stream all lines from input file
        .map(s -> Map.entry(Integer.parseInt(s.split(": ")[1]), s.split(": ")[0].strip())) // split and map to Map.Entry
        .sorted(Map.Entry.<Integer, String>comparingByKey()) // sort
        .map(entry -> entry.getValue() + ": " + entry.getKey()) // map to required format
        .collect(Collectors.joining("\n")); // collect back to string

Files.writeString(Highscores.toPath(), save);

great question, and this can be easily solved. Simply read the File as a Collection of String objects that represent each line. Then split the line by the : or whitespace character and get the score value and compare based off of that. Then you can simply map back to a List of String by joining the values. You can then write using Files.write!

Path path = Paths.get("Scoreboard/Level_" + levelID + "_Highscore.txt");

List<String> lines = Files.readAllLines(path);

        List<String> linesOrdered = lines.stream()
                .map(line -> line.replaceAll(" ", "").split(":"))
                .sorted(Comparator.comparingInt(strings -> Integer.parseInt(strings[1])))
                .map(values -> String.join(" ", values))
                .collect(Collectors.toList());

Files.write(path, linesOrdered);
Related