Java 为什么我的地图坏了?

Java 为什么我的地图坏了?,java,multithreading,reference,map,hashtable,Java,Multithreading,Reference,Map,Hashtable,场景:创建具有包含用户对象的房间对象的服务器 我想按Id(字符串)将房间存储在某种类型的地图中 期望的行为: 当用户通过服务器发出请求时,我应该能够从库中按id查找文件室,然后将用户添加到文件室,如果请求需要的话 目前,我在我的Library.java类中使用静态函数,其中存储地图以检索房间: public class Library { private static Hashtable<String, Rooms> myRooms = new Hashtable<Str

场景:创建具有包含用户对象的房间对象的服务器

我想按Id(字符串)将房间存储在某种类型的地图中

期望的行为

当用户通过服务器发出请求时,我应该能够从库中按id查找文件室,然后将用户添加到文件室,如果请求需要的话

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

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);
  }
}
公共类库{
私有静态哈希表myRooms=新哈希表();
公共静态addRoom(字符串s,Room r){
我的房间。放(s,r);
}
公共静态房间getRoomById(字符串s){
返回我的房间。获取(s);
}
}
在另一个类中,我将执行与myRoom.addUser(user)等效的
myRoom

我使用Hashtable观察到,无论我向getRoomById返回的文件室添加了多少次用户,该用户以后都不在文件室中

我认为在Java中,返回的对象本质上是对数据的引用,即哈希表中具有相同引用的相同对象;但事实并非如此。有没有办法让这种行为发生?也许用某种包装纸?我只是使用了错误的地图变体吗


帮助?

非常奇怪的是,您将
myRooms
声明为
Hashtable
(复数
Rooms
),但您
单数
roomr
放在
addRoom

您是否正在尝试执行某种多重映射,其中一个键可以映射到多个值?如果是这样,那么要么我们使用实现,要么将自己的实现实现为
映射
(将一个键映射到一组值)

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

根据引用等式的定义,
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"
Object someObject=新对象();
Map Map=newhashmap();
map.put(“key1”,someObject);
System.out.println(map.get(“key1”)==someObject);//打印“真实”
someObject=“someother”;
System.out.println(map.get(“key1”)==someObject);//打印“假”
以上是预期的行为

有时人们在使用
映射时会遇到问题,因为他们的键对象没有正确地实现
hashCode
equals
契约,但是如果您使用
String
作为键,这应该不是问题

顺便说一下,
Hashtable
HashMap
中有一个更新、更性感的表亲。我注意到问题中的
多线程
标记,因此如果您确实需要
同步
功能,可以使用

在这两种情况下,无论您使用的是
HashMap
还是
Hashtable
,您都希望将
myRooms
声明为
Map
(请参见有效Java第二版第52项:通过对象的接口引用对象)

相关问题

您的代码甚至可以编译吗

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);
  }
}
公共类库{
私有静态哈希表myRooms=新哈希表();
公共静态addRoom(字符串s,Room r){//您的哈希表包含房间,但您添加了一个房间
我的房间。放(s,r);
}
publicstaticroomgetroombyid(字符串s){//再次返回一个Room,而不是Rooms
返回我的房间。获取(s);
}
}

只要看看这个,它就不应该编译。现在我只能假设这是一个打字错误,如果是这样的话,那么给我们看看
房间
代码,在那里你试图添加一个用户到房间。

看到房间的代码也会很好。我会发现,只要我发了这篇文章,我就会把这些点连接起来。在四个月没有看这段代码之后,我要回到这里。我在用户中隐藏了一小段代码,基本上就是这样做的:setRoomPseudo(Room r){if(myRoom!=null)myRoom.removeMe()myRoom=r},所以我忘记了它是这样工作的,操作是无序的。修正了,麻烦你了。毕竟我懂地图,懂java,只是我自己不懂!如果
Room扩展/实现Rooms
,它将被编译。不过,这很奇怪。它会发现,我一发布这篇文章,就把这些点连接起来了。在四个月没有看这段代码之后,我要回到这里。我在用户中隐藏了一小段代码,基本上就是这样做的:setRoomPseudo(Room r){if(myRoom!=null)myRoom.removeMe()myRoom=r},所以我忘记了它是这样工作的,操作是无序的。修正了,麻烦你了。毕竟我懂地图,懂java,只是我自己不懂!它会发现,一旦我发布这篇文章,我就会把这些点连接起来。在四个月没有看这段代码之后,我要回到这里。我在用户中隐藏了一小段代码,基本上就是这样做的:setRoomPseudo(Room r){if(myRoom!=null)myRoom.removeMe()myRoom=r},所以我忘记了它是这样工作的,操作是无序的。修正了,麻烦你了。毕竟我懂地图,懂java,只是我自己不懂!