Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Is anything what could I improve on my code?

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


public class Helper {

    public static Map<User, BigDecimal> createPlayersScoreMap(List<User> users, List<Score> scores) {
        List<User> players = getPlayers(users);
        Map<User, BigDecimal> playersScoreMap = new HashMap<User, BigDecimal>();

        for (User player: players) {
            BigDecimal sumScore = new BigDecimal(0);
            for (Score score: scores) {
                if (player.equals(score.getPlayer())) {
                    sumScore = sumScore.add(score.getResult());
                }
            }
            playersScoreMap.put(player, sumScore);
        }
        return playersScoreMap;
    }

    private static List<User> getPlayers(List<User> users) {
        List<User> filteredUsers = new ArrayList<User>(users);
        for (Iterator<User> it = filteredUsers.iterator(); it.hasNext();) {
            if (!it.next().isPlayer())
                it.remove(); 
        }
        return filteredUsers;
    }

}
share|improve this question

2 Answers 2

Helper is not a good class name. You should be able to come up with something that provides more context to what the functions are doing.

In getPlayers(), I would loop and add instead of adding all and then removing.

private static List<User> getPlayers(List<User> users) {
    List<User> filteredUsers = new ArrayList<User>();
    for (User user : users) {
        if (user.isPlayer()) {
            filteredUsers.add(user);
        }
    }
    return filteredUsers;
}

I also added curly braces around the if block. It's not necessary, but it will prevent errors if you need to add an extra line later. You also included them in createPlayersScoreMap(), so it's best to be consistent.

If you have a large number of players and scores, you can make createPlayersScoreMap() more efficient (in terms of Big O processing). If n is the number of users and m is the number of scores, the method is currently O(n*m). However, if you sum all the scores first and then filter the players, you can get O(n+m).

public static Map<User, BigDecimal> createPlayerScores(List<User> users, List<Score> scores) {
    List<User> players = getPlayers(users);
    Map<User, BigDecimal> playerScores = new HashMap<User, BigDecimal>();

    for (Score score: scores) {
        User player = score.getPlayer();
        BigDecimal sumScore = score.getResult();
        if (playerScores.containsKey(player) {
            sumScore = sumScore.add(playerScores.get(player));
        }
        playerScores.put(player, sumScore);
    }
    Map<User, BigDecimal> filteredScores = new HashMap<User, BigDecimal>();
    for (User player : players) {
        filteredScores.put(player, playerScores.get(player));
    }
    return filteredScores;
}

I also change the name of the function/variable. They type system makes it obvious that you are dealing with a Map, you don't need to include it in the variable name. If the calling method has Lists and Maps that deal with players and scores, then it might be acceptable to include the type as part of the variable name.

share|improve this answer
1  
In the original code there is a new BigDecimal(0) this should be replaced with BigDecimal.ZERO, otherwise this review covers it all I think. – bowmore Aug 15 '13 at 13:55
    
@bowmore: Good catch. I've never actually used BigDecimal, so I didn't know that existed. – unholysampler Aug 15 '13 at 14:02
    
I think you can also eliminate the filteredScores Map. After all in playerScores, only those users are missing that are players without a score. So the second loop can simply loop users and add en entry for users that are players without a score. – bowmore Aug 16 '13 at 5:42

The Helper is an absolutely ridicoulus class name. How about PlayerScoreMap? This might be a good idea because createPlayerScoreMap is actually a constructor! (As evidenced by the name).

The whole getPlayers helper is unneccessary, and backwards: All this does is to delete those users from a copied list that are not players, so that they are not iterated in the constructor. I have a better idea: Simply skip over those users that you don't like, e.g.

for (User user : users) {
  if (!user.isPlayer()) continue;

  ... // score summation
}

Why are you using BigDecimals? This is only reasonable when you have a scoring system that actually uses arbitrary fractional values (which is quite unusual). Most systems use integer scores or fixed point values, which can easily be translated to integers. Even if scores can be arbitrary values, an insignificant loss of precision may be acceptable. But this relies on the number of scores and the problem space, which I do not know about.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.