-1

this is the player class

package day6;

public class Player {
int playerId;

public Player(int playerId) {
    super();
    this.playerId = playerId;
}

public int getPlayerId() {
    return playerId;
}

}

this is the position class

package day6;

public class Position {


    private int positionNumber = 0;

    public Position(int positionNumber) throws Exception {
        super();
        this.positionNumber = positionNumber;

    }

    public int getPositionNumber() {
        return positionNumber;
    }

    }

this is the game class

 package day6;

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Random;

    public class Game {


        private int numberOfPlayers;


        HashMap<Player, Position> hashMapForPositionOfPlayer = new HashMap<Player, Position>(numberOfPlayers);

        @SuppressWarnings("unchecked")
        public Game(int numberOfPlayers) throws Exception {
            super();

            this.numberOfPlayers = numberOfPlayers;
            for (int i = 0; i <numberOfPlayers; i++) {
                hashMapForPositionOfPlayer.put(new Player(i), new Position(0));
            }
        }

        public void play() throws Exception {

            Position currentPosition;




                for (int i = 0; i < numberOfPlayers; i++) {

                    Player player = new Player(i);
                    currentPosition = hashMapForPositionOfPlayer.get(player);
                    int value = currentPosition.getPositionNumber();

                    }
                }
            }

I tried to run the program Game class and game.play() but it is showing null value to the 0th value of the hashmap.

it means currentPosition=null for hashmap of key value 0.

Help me..

Tim
  • 35,413
  • 11
  • 95
  • 121
Pratap M
  • 1,059
  • 3
  • 21
  • 31

6 Answers6

4

Since you're using Player instances as keys of the HashMap, it should implement hashCode() and equals() consistently, so that two Player instances are considered to represent the same player when their playerId's are equal.

Without implementing equals() properly, the following snippet would return false:

Player p1 = new Player(1);
Player p2 = new Player(1);
return p1.equals(p2);

Also, given the nature of the Map implementation you've chosen, HashMap, the check for existing keys in the Map will be associated to their hashCode, so it is necessary to also implement hashCode to reflect that two Player instances are equal if their playerId's are.

The following question might be useful to you: Understanding the workings of equals and hashCode in a HashMap.

Sample code:

package day6;

public class Player {
    int playerId;

public Player(int playerId) {
    super();
    this.playerId = playerId;
}

public int getPlayerId() {
    return playerId;
}

public int hashCode(){
    return playerId.hashCode();
}

public boolean equals(Object o){
    if (o instanceOf Player) { 
        return playerId.equals( ((Player)o).getPlayerId());
    }
    return false;
}
}
Community
  • 1
  • 1
Xavi López
  • 27,550
  • 11
  • 97
  • 161
3

Firstly, I would use an ArrayList for indexed from 0 access.

In your case, the problem you have is that Player doesn't implement equals and hashCode so that means that new Player(0) and new Player(0) are two different objects which happen to have a value which is the same.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    the idea for my programs is to learn programming with hashMap...so i did with the implementaion..i got the solution. – Pratap M Sep 07 '12 at 07:07
2

The problem is that two different instances of your Player class won't compare equal.

Player player1 = new Player(0);
Player player2 = new Player(0);
System.out.println(player1.equals(player2));

But I think that a hashmap isn't an appropriate structure here. The solution is to store the players in an array.

for (int i = 0; i < numberOfPlayers; i++) {
    Player player = players[i];
    // etc...
}
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 2
    The hashCode() has to match before equals is called. ;) – Peter Lawrey Sep 06 '12 at 12:10
  • 1
    @PeterLawrey: Yes, but remember that if the objects are equal then the hashcode **must** also be equal (assuming that the class is implemented correctly of course, and it is in this case). – Mark Byers Sep 06 '12 at 12:18
2

Root cause is that Player does not implement hashCode and equals. So when hashMapForPositionOfPlayer.get(player) searches the map, it will look for an object with another hashCode then the object that was put in.

Add the following code to Player, it should do the trick

@Override public int hashCode() { return 0; }

@Override
public boolean equals(Object obj) {
    Player other = (Player) obj;
    return this.playerId == other.playerId;
}
Dan Bergh Johnsson
  • 964
  • 10
  • 14
  • Well, it does not violate the contract. As *all* objects produce the same integer result, then specifically two equal objects will also do so. However, it does not spread the hashCodes very well, so performance of HashMap will be linear search. – Dan Bergh Johnsson Sep 06 '12 at 13:31
  • Indeed :) Don't know how did i end up getting it the other way around. +1 to you, sir! – Xavi López Sep 06 '12 at 13:50
1

You create a series of players in the constructor of Game and put them in your HasMap, but when you do your look up in the play method, you create new players and try using those as the look up.

These are two different references, thus the HashMap can't find the player (you just created) and returns null

Create & populate HasMap

hashMapForPositionOfPlayer.put(new Player(i), new Position(0));

Create & find ... Null

Player player = new Player(i); // this reference does not exist in the HasMap
currentPosition = hashMapForPositionOfPlayer.get(player);
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

Or forget about using Player as the key and use the player ID instead.

Map<Integer, Position> 

would require a lookup for position using the player ID.

duffymo
  • 305,152
  • 44
  • 369
  • 561