Почему Map.put () перезаписывает существующие значения в уже существующих парах ключ / значение? - PullRequest
0 голосов
/ 05 апреля 2019

Map.put () перезаписывает существующие значения сам по себе, несмотря на ввод уникального значения.

Я инициализирую синглтон объекта "Игра", в котором у меня есть карта комнат (и игроков).

Когда я вводю новую пару ключ / значение в roomsList, вот так: roomsList.put (uniqueKey, new Room (uniqueKey, name)), новая пара ключ / значение добавляется на карту, но остальные пары (каждая с уникальным идентификатором) также перезаписывают свои значения.

Я пытался вставить новую комнату в Spring Controller с помощью Game.getRoomsList (). Put () создание отдельного объекта для клиентских сообщений, чтобы вместо сообщения проигрывателя - поэтому параметр Контроллера имеет тип объекта NewRoomMessage И даже помещая пары ключ / значение непосредственно в приватный конструктор Game ...

Странно то, что с моим Map PlayersList все работает нормально ..

Файлы в порядке связи

lobby.js

Этот сценарий отправляет имя и сгенерированный roomId на конечную точку сервера / game / sessionId, где sessionId - идентификатор веб-сокета игрока, roomId - это вновь сгенерированный идентификатор, а name - это ввод пользователя для нового имени комнаты

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

Это мой контроллер Spring, который обрабатывает сообщения от Player и предназначен для создания комнат в игре. RoomsController

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

Это игровой объект, представляющий собой синглтон, с которым общается мой Spring-сервер.

Game.java

пакет cz.vse.pavm07.bp.objects;

import java.util.HashMap; import java.util.Map;

import org.springframework.stereotype.Controller;

@Controller
public class Game{
    private static Game game;
    /* 
    private static List<Player> players = new ArrayList<Player>();
    private static List<Player> playersToRemove = new ArrayList<Player>(); 
    */
    private static Map<String, Player> playersList = new HashMap<String, Player>();
    private static Map<String, Player> playersToRemove = new HashMap<String, Player>();
    private static Map<String, Room> roomsList = new HashMap<String, Room>();
    private static Map<String, Room> roomsToRemove = new HashMap<String, Room>();

// LAZY SINGLETON GAME
    private Game() {}

    public static Game getInstance() throws Exception{
        if(game == null) {
            game = new Game();
        }
        return game;
    }
    /* This is the method I have issues with, it somehow overwrites already existing values in my Map of Rooms */
    /* ROOMS LIST */

    public static boolean addRoom(Player player) {
        if (!roomsList.containsKey(player.getRoomId())) {
            roomsList.put(player.getRoomId(), new Room(player.getRoomId(), player.getMessage()));
            return true;
        }       
        return false;
    }


    /*  PLAYERS LISTS */
    /*  Method adds new player to the playersList and it works right */ 
    public static boolean addPlayer(String sessionId, String name) {
        if (playersList.containsKey(sessionId)) {
            return false;
        } else {
            playersList.put(sessionId, new Player(sessionId, name));
            return true;
        }
    }
}

Это конструктор моей комнаты Room.java

public Room (String ID, String name) {
        this.ID = ID;
        this.name = name;
    }

Пример вывода:

NEW ROOM IS ADDED
I am printing out the keyset of my roomsList, and then for each room its key, its ID and its Name
[_y46r22hdu]
The Key of the Room is_y46r22hdu, The ID is _y46r22hdu and the Name of the room isRoom1

NEW ROOM IS ADDED
I am printing out the keyset of my roomsList, and then for each room its key, its ID and its Name
[_jxltglk5z, _y46r22hdu]
The Key of the Room is_jxltglk5z, The ID is _jxltglk5z and the Name of the room isRoom2
The Key of the Room is_y46r22hdu, The ID is _jxltglk5z and the Name of the room isRoom2

Я ожидаю, что Карта добавит новый Объект без перезаписи уже существующих пар ключ / значение ...

Ссылка на репозиторий этого проекта находится здесь: https://github.com/MartinPavelka/chaser-server

1 Ответ

14 голосов
/ 05 апреля 2019

Ошибка в вашем Room классе.И 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;

Возможно, вы захотите изменить некоторые из ваших статических методов на методы экземпляра ... и взгляните на остальные поля.По сути, вам нужно позаботиться о том, какие аспекты состояния должны быть общесистемными (статическими) и какие аспекты предназначены для каждого экземпляра.(Вы должны также взглянуть на те же проблемы для Game. Принципиально статические поля обычно довольно редки в приложении. Когда вы в конечном итоге почти все свои поля статичны - в соответствии с вашим проектом на данный момент), что говорит о том, что вам нужноснова посмотреть на дизайн.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...