为什么我的地图坏了?

时间:2010-05-24 02:16:51

标签: java multithreading reference map hashtable

场景:创建一个服务器,其中包含 Room 对象,其中包含用户对象。

我想通过 Id (一个字符串)将房间存储在某种 Map 中。

所需行为

当用户通过服务器发出请求时,我应该可以从库中查找房间ID,然后将用户添加到房间,如果这是请求所需的。

目前我在我的Library.java类中使用静态函数,其中存储了Map以检索房间:

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返回的房间,用户以后都不在房间内。

我认为在Java中,返回的对象本质上是对数据的引用,Hashtable中的相同对象具有相同的引用;但是,它不是那样的。有没有办法得到这种行为?也许用某种包装?我只是使用错误的地图变体吗?

帮助?

2 个答案:

答案 0 :(得分:2)

您将myRooms声明为Hashtable<String, Rooms>(复数Rooms),但put Room raddRoomMap<K,Set<V>>,这是非常奇怪的。

您是否尝试进行某种多重映射,其中一个键可以映射到多个值?如果是这样,那么请使用Guava实现,或将您自己的实现作为get(将键映射到 set 的值)。

但是,我不确定这是否是你的根本问题。

正确的是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时出现问题,因为他们的主要对象未正确实施equalsString合同,但如果您使用Hashtable作为键,则不应该是一个问题。

顺便说一下,HashMapmultithreading中有一个更新,更性感的堂兄。我注意到问题中的synchronized标记,因此,如果您确实需要HashMap功能,则可以使用Collections.synchronizedMap

在任何一种情况下,无论您使用Hashtable还是myRooms,都希望将Map简单地声明为{{1}}(请参阅 Effective Java 2nd Edition,第52项:通过接口引用对象)。

相关问题

答案 1 :(得分:0)

你的代码甚至可以编译吗?

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);
  }
}

只要看一下,它就不应该编译。现在我只能假设它是一个拼写错误,如果是这种情况,那么请向我们展示您尝试将用户添加到房间的Room代码。