为什么Map.put()覆盖现有键/值对中的现有值?

时间:2019-04-05 12:07:43

标签: java spring websocket hashmap

尽管放置了唯一值,但Map.put()本身会覆盖现有值。

我正在初始化对象“游戏”的单例,其中有“房间(和玩家)地图”。

当我在roomsList中输入新的键/值对时,如下所示: roomsList.put(uniqueKey,new Room(uniqueKey,name)),新的键/值对已添加到地图中,但其余对(每个都有唯一的标识符)的值也被覆盖。

我尝试使用Game.getRoomsList()。put()在Spring Controller中放置一个新房间 为客户端消息创建一个单独的对象,以便代替播放器消息, -因此,控制器的参数属于对象类型NewRoomMessage 甚至直接将键/值对放在私有Game构造函数中...

奇怪的是,使用我的Map playerList,一切正常。

文件按通信顺序

lobby.js

此脚本将名称和生成的roomId发送到服务器端点/ game / sessionId,其中sessionId是玩家的websocket标识符, roomId 是新生成的ID,名称是用户输入的新房间名称

kapt

这是我的Spring控制器,用于处理来自Player的消息,并用于在游戏中创建房间 RoomsController

kapt "android.arch.persistence.room:compiler:$room_version"

这是一个游戏对象,它是一个Singleton,我的Spring服务器与之通信

Game.java

软件包cz.vse.pavm07.bp.objects;

import java.util.HashMap; 导入java.util.Map;

导入org.springframework.stereotype.Controller;

annotationProcessor "android.arch.persistence.room:compiler:$room_version" 

这是我的房间构造函数 Room.java

function createRoom() {
    name = $('#inputRoomName').val();
    roomId = '_' + Math.random().toString(36).substr(2, 9);
    console.log(roomId);
    stompClient.send('/game/'+sessionId, {}, JSON.stringify({'message': name, 'roomId': roomId}));
}

示例输出:

@Controller
public class RoomsController {
    @MessageMapping("/game/{sessionId}")
    @SendTo("/topic/game/{sessionId}")  
    public RoomMessage createRoom(@DestinationVariable String sessionId, Player player) throws Exception {
        Game game = Game.getInstance();
        game.addRoom(player);
        return new RoomMessage("Room with the ID " + player.getRoomId() + " created");
    }
}

我希望地图添加一个新对象,而不覆盖已经存在的键/值对...

此项目存储库的链接在这里:https://github.com/MartinPavelka/chaser-server

1 个答案:

答案 0 :(得分:14)

错误出在您的Room类中。 const ScrapeSchema = new Schema({ title:{ type: Array, "default" : [] }, date:{ type: Array, "default" : [] }, summary:{ type: Array, "default" : [] } }); name都是静态字段,而您期望每个实例都具有一对单独的字段。

所以这个:

ID

应该是

private static String name;
private static String ID;

我个人也将它们设置为private String name; private String id; // Name changed to follow conventions ,以明确它们在对象的整个生命周期中不会改变:

final

您还将希望将某些静态方法更改为实例方法...,然后查看其余字段。基本上,您需要注意状态的哪些方面应为类型范围(静态),以及哪些方面应按实例进行。 (对于private final String name; private final String id; ,您也应该查看相同的问题。基本静态字段通常在应用程序中很少见。当最终几乎所有字段都是静态的时-根据当前项目的情况-这表明您需要再次查看设计。)