场景:创建具有包含用户对象的Room对象的服务器.
我想将房间存储在某种地图中,用Id(字符串).
期望的行为:
当用户通过服务器发出请求时,我应该能够从库中查找房间ID,然后将用户添加到房间,如果这是请求所需的.
目前我在我的Library.java类中使用静态函数,其中存储了Map以检索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);
}
}
在另一个类中,我将完成相当于myRoom.addUser(user)的操作;
我正在使用Hashtable观察的是,无论我将多少次用户添加到getRoomById返回的Room,用户以后都不在房间内.
我认为在Java中,返回的对象本质上是对数据的引用,Hashtable中的相同对象具有相同的引用;但是,它不是那样的.有没有办法得到这种行为?也许用某种包装?我只是使用错误的地图变体?
救命?
最佳答案 将myRooms声明为Hashtable< String,Rooms>这是非常奇特的. (多个房间),但你在addRoom中放了一个单一的房间r.
您是否尝试进行某种多重映射,其中键可以映射到多个值?如果是这样,那么请使用Guava实现,或者将您自己的实现为Map< K,Set< V>> (将键映射到一组值).
不过,我不确定这是否是你的根本问题.
正确的是,get的返回值应该是引用相等定义的同一个对象,就像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"
以上是预期的行为.
有时人们遇到Map有问题,因为他们的关键对象没有实现hashCode并且正确地等于合约,但是如果你使用String作为键,这应该不是问题.
顺便说一句,Hashtable在HashMap中有一个更新,更性感的堂兄.我注意到问题中的多线程标记,因此如果您确实需要同步功能,则可以使用Collections.synchronizedMap
在任何一种情况下,无论是使用HashMap还是Hashtable,都希望将myRooms简单地声明为Map(请参阅Effective Java 2nd Edition,Item 52:通过其接口引用对象).
相关问题
> Overriding equals and hashCode in Java
> Understanding the workings of equals and hashCode in a HashMap
> Java hashmap vs hashtable
> Difference between a Deprecated and Legacy API?