Solved Getting top 10 kills

Discussion in 'Plugin Development' started by Tim_M, Jul 30, 2021.

  1. Offline


    I'm making a plugin that keeps track of players kills, deaths etc. There are leaderboards with top kills and such. The simplest way is going through the config and checking. But let's imagine a server has had like 5k unique players. Then going through the config takes a stupid amount of time and lags the server. (It also has to be done everytime someone opens the leaderboard GUI). In order to recude I/O calls I made it so that when a server starts it copies all the data from the config into several HashMap which contain player's UUID and their kills/deaths etc. Whenever the data is changed the hashmap get's sorted with a function I made here:
    public void sortKills()
            HashMap<String, Integer> unordered = new HashMap<String, Integer>();
            HashMap<String, Integer> ordered = new HashMap<String, Integer>();
            String playername;
            int highestvalue = 0;
            for (int i = 0; i < unordered.size(); i++)
                for (Entry<String, Integer> e : unordered.entrySet())
                    if (e.getValue() > highestvalue)
                        highestvalue = e.getValue();
                        playername = e.getKey();
                        ordered.put(playername, highestvalue);
    My problem is that sorting the data when the data changes is that it causes:
    Is there any way to work around this?

    if it matters the error happens at:
    for (Entry<String, Integer> e : unordered.entrySet())
    Any answers are appreciated.

    Issue solved.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
    Last edited by a moderator: Jul 30, 2021
  2. Offline


    ConcurrentModificationException is called when you edit a sequence at the same time you iterate through it. For example, the following code would cause a Concurrent Modification Exception:
    List<String> list = new ArrayList<String>();
    for (String s : list) list.remove(s);
    To fix it, you could change the line to
    for (String s : list.toArray(new String[list.size()])) list.remove(s);
    or anything that makes a duplicate list to iterate through

    As for efficiency in getting the leaderboards, you should have them only periodically update (maybe every 10 minutes), and use a sorting algorithm run over an asynchronous bukkit runnable. That way, when a player looks at the leaderboards, it just shows them the pre-calculated values for 1st place, 2nd place, etc.
    KarimAKL and davidclue like this.
  3. Offline


    Just to add on (this will already work); but you could also create an empty array:
    1. list.toArray(new String[0])
  4. Offline


    Thank you for the responses! I solved this issue by just sorting the list when the data changes. I forgot to make an async schedule call so thanks for that!

Share This Page