3

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!

Box
  • 91
  • 6
  • 1
    How about making a HighScore Class, containing player name and score, make an array of HighScore, filling up it with the highscores, then sort them out in the array, and then writing to the file. To sort them you can implement the Comparable interface and your own compareTo, which is comparing the scores. – codemonkey May 19 '20 at 12:49

2 Answers2

3

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);
Aniket Sahrawat
  • 12,410
  • 3
  • 41
  • 67
  • When you say using a SortedMap, I suppose you mean making an Interface and if it is, when I do, should I add the names as well? ( like the first snippet of your code ) Because those names aren't stored anywhere besides the soon to be .txt file and in the memory since I just have a part for the person to insert the name and keep it as a string. I tried using your code and it didn't like it for some reason, when I made the Interface and pasted the code ( Just to see how it would work ) – Box May 22 '20 at 18:05
2

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);
Jason
  • 5,154
  • 2
  • 12
  • 22
  • Whenever I test this one, it gives me an: Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1 and points to this line: .sorted(Comparator.comparingInt(strings -> Integer.parseInt(strings[1]))) Now, I always try to understand it before rewriting the code but if you could explain me your code, I'd be thankful! – Box May 22 '20 at 18:01