I am designing a Baseball League scoreboard of TOP 5 Batsmen. I am using a TreeMap
with player_name as value
and Player
as key
.
Map<Player, String> players = new TreeMap<>(Collections.reverseOrder());
Player
class has natural ordering as per runs scored in the league
compare(this.leagueRuns, otherPlayer.leagueRuns)
leagueRuns
are updated contantly during the game and the TOP 5 Batsmen scoreboard should also change accordingly. Below is the code to update league runs for a player and re-insertion into TreeMap
. After updating, TOP 5 entries from Map are retrieved and displayed.
public void updateRuns(String playerName, int runsScored) {
Iterator<Entry<Player, String>> playersEntries = players.entrySet().iterator();
Player player = null;
while (playersEntries.hasNext()) {
Entry<Player, String> currentPlayer = playersEntries.next();
if (currentPlayer.getValue().equalsIgnoreCase(playerName)) {
player = currentPlayer.getKey();
}
}
players.remove(player);
player.addRuns(runsScored);
players.put(player, player.getName());
}
Everything is working fine but I have following concerns:
Player
I am using it as Key
in TreeMap
. But have to iterate through the whole Map
to find Player
being updated. Hence time complexity degraded from O(1) to O(n). And gets even worse as I have to remove that Player
, update it and re-insert otherwise changes won't take effect. Hence O(n + logn)
. Is there a way to sort Player
as per natural ordering and also be able to search in O(1). I guess re-insertion cannot be avoided.leagueRuns
is updated for a player, the whole TreeMap
has to be re-ordered. Do you think creating a separate min-heap of TOP 5 Batsmen can resolve this issue and is a viable idea.You should support 2 structures:
So update scoreboard will be O(log(N)):
Map<String, Player> players;
SortedSet<Player> scoreboard;
public void updateRuns(String playerName, int runsScored) {
Player player = players.get(playerName);
if (player == null) {
player = new Player(playerName, runsScored);
} else {
scorepoard.remove(player);
player.addRuns(runsScored);
}
scoreboard.add(player);
}
If you make Player class unmodifiable (preferred way), you'll get the same O(log(N)):
public void updateRuns(String playerName, int runsScored) {
Player player = players.remove(playerName);
if (player == null) {
player = new Player(playerName, runsScored);
} else {
scorepoard.remove(player);
player = new Player(playerName, player.getRuns() + runsScored);
}
players.put(playerName, player);
scoreboard.add(player);
}