Why is my card broken?

Scenario : creating a server with Room objects that contains user objects.

I want to save rooms on any map by identifier (string).

The desired behavior:

When a user makes a request through the server, I should be able to search for the room by ID from the library, and then add the user to the room, if necessary for the request.

I am currently using a static function in my Library.java class, where the Map is stored to retrieve rooms:

public class Library { private static Hashtable<String, Rooms> myRooms = new Hashtable<String, Rooms>(); public static addRoom(String s, Room r) { myRooms.put(s, r); } public static Room getRoomById(String s) { return myRooms.get(s); } } 

In another class, I will make the equivalent of myRoom.addUser(user);

What I am observing with the Hashtable is that no matter how many times I add the user to the Room returned by getRoomById, the user is not in the room later.

I thought that in Java, the returned object was essentially a data reference, the same object that was in the Hashtable with the same references; but he does not behave like that. Is there any way to get this behavior? Maybe with some kind of wrapper? Am I just using the wrong map option?

reference

+4
source share
2 answers

It is very strange that you declare myRooms as Hashtable<String, Rooms> (plural Rooms ), but you put singular Room r in addRoom .

Are you trying to make some kind of multimap where the key can display several values? If so, then either we, or Guava , or implement your own as Map<K,Set<V>> (map the key to the set of values).

I am not sure if this is your main problem.

It is true that the return value of get must be the same object as defined by referential equality, like the value used in put .

  Object someObject = new Object(); Map<String,Object> map = new HashMap<String,Object>(); map.put("key1", someObject); System.out.println(map.get("key1") == someObject); // prints "true" someObject = "something else"; System.out.println(map.get("key1") == someObject); // prints "false" 

Expected behavior is higher.

Sometimes people have problems with Map , because their key objects do not implement the hashCode and equals contract correctly, but if you use String as keys, this should not be a problem.

By the way, Hashtable has a newer, sexier cousin in HashMap . I noticed the multithreading tag in the question, so if you really need the synchronized function, you can use Collections.synchronizedMap

In any case, whether you use a HashMap or a Hashtable , you want to declare myRooms simply as a Map (see Effective Java 2nd Edition, paragraph 52: refer to objects by their interfaces).

Related Questions

+2
source

Is your code compiled?

 public class Library { private static Hashtable<String, Rooms> myRooms = new Hashtable<String, Rooms>(); public static addRoom(String s, Room r) { // Your hashtable holds Rooms yet you add a Room myRooms.put(s, r); } public static Room getRoomById(String s) { // Again, returning a Room, instead of Rooms return myRooms.get(s); } } 

Just by looking at it, it should not compile. Now I can only assume that it was a typo, and if this is the case, show us the Room code where you are trying to add the user to the room.

0
source

Source: https://habr.com/ru/post/1310697/


All Articles