java – 为什么我的地图坏了?

场景:创建具有包含用户对象的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?

点赞