Вопрос Получение ключа из конфига по значению

Alex-Novosiber

Пользователь
Сообщения
39
Суть вопроса следующая: У меня есть конфиг, куда складываю ИмяИгрока, его ИмяРегиона, время последнего захода на сервер, и название мира, в котором регионы. Вот пример конфига:

YAML:
regions:
  testo:           # ИмяИгрока
      world:       # Имя мира с регионами
      - ol333      # ИмяРегиона
      world2:      # Имя ДРУГОГО мира с регионами
      - home1      # ИмяРегиона
      playerUUID: ad7b1b21-8130-376d-99f0-5da47a5cad12
      LastPlayed: 1598666067974           # Время последнего захода на сервер
  testerrr:            # ИмяИгрока
      world:
    - myhome2
    - testerrrhome333
    playerUUID: ae5da884-920b-3e1e-8d52-de4371490718
    LastPlayed: 1598672185088

Стоит цель получить время последнего захода на сервер, и сравнить с текущим временем. Если не заходил больше месяца - сношу регионы и удаляю его из конфига. Для этого надо получить ИмяИгрока, содержащего это время. Как я могу получить ИмяИгрока (ключ) , содержащий значение ?
Думал ложить всё последовательно в массивы, например массив с ИменемИгрока , и другой массив с временем захода на сервер, получить индекс просроченного времени в массиве, и по этому индексу получить ИмяИгрока в другом массиве с именами. Вроде всё должно ложится в массивы в соответствующей последовательности. НО мля... это такие грабли.... ?
Другой вариант - переназначить расположение элементов массива, чтобы подогнать ВремяЗахода и ИмяИгрока в удобный для поиска формат, но пока ничего не придумал. Тема интересная, может кто подскажет как проще и надёжнее сделать ?
 
Последнее редактирование:
Решение
Массивы здесь вообше не вариант. Загружай все данные в Map (HashMap) коллекцию, где ключом будет ник игрока, а значением - твой собственный обьект со всеми нужными данными этого игрока. Так ты будешь моментально получать нужного тебе игрока не перебирая ничего и не делая костылей.

Так же для большого количества я бы не рекомендовал хранить в Yaml, а задуматься про базы данных (H2 если локально в файле, MySQL если глобально)
Массивы здесь вообше не вариант. Загружай все данные в Map (HashMap) коллекцию, где ключом будет ник игрока, а значением - твой собственный обьект со всеми нужными данными этого игрока. Так ты будешь моментально получать нужного тебе игрока не перебирая ничего и не делая костылей.

Так же для большого количества я бы не рекомендовал хранить в Yaml, а задуматься про базы данных (H2 если локально в файле, MySQL если глобально)
 
Можно пример цикла добавления в мапу Имени (как ключ) и Времени (как значение), или наоборот ?
Java:
Map<String, Long> map = new HashMap<>();

FileConfiguration config = ...;
ConfigurationSection section = config.getConfigurationSection("regions");

// Параметр false значит, что с секции ключи берутся только первого уровня
// т.е. в твоем случае это будут ники игроков
for (String playerName : section.getKeys(false)) {
    // Секция работает точно так же как config
    long lastPlayed = section.getLong(playerName + ".LastPlayed");
    map.put(playerName, lastPlayed);
}

// Получить значение

// Юзается getOrDefault(...) вместо get(...), так как если игрока
// не будет в мапе, будет возвращаться null, а мы превращаем обьект Long
// в примитивный long, будет исключение выпадать.
long time = map.getOrDefault(playerName, -1L);

P.S. Проверять есть ли в мапе значение или обрабатывать это можно несколькими способами, я подобрал самый подходящий и простой вариант для твоего случая. Если в мапе значения не будет - вернется число -1.
 
Спасибо огромное ! Это лучшее решение моей проблемы ! ? ?
Авто объединение сообщений:

// Юзается getOrDefault(...) вместо get(...), так как если игрока // не будет в мапе, будет возвращаться null, а мы превращаем обьект Long // в примитивный long, будет исключение выпадать.
Эта фишка годнота !
map.getOrDefault("number", 0);
Java:
Map<String, Integer> map = new HashMap<>();
map.put("number", 100500);

Integer value = map.getOrDefault("number", 0);
System.out.println(value); // 100500


Integer valOrDefault = map.getOrDefault("I forgot my key", 0);
System.out.println(valOrDefault); // 0
Спасибо ещё раз, дружище
 
Последнее редактирование:
Спасибо огромное ! Это лучшее решение моей проблемы ! ? ?
Авто объединение сообщений:


Эта фишка годнота !
map.getOrDefault("number", 0);
Java:
Map<String, Integer> map = new HashMap<>();
map.put("number", 100500);

Integer value = map.getOrDefault("number", 0);
System.out.println(value); // 100500


Integer valOrDefault = map.getOrDefault("I forgot my key", 0);
System.out.println(valOrDefault); // 0
Спасибо ещё раз, дружище
В случае с getOrDefault() тебе не обязательно в Integer писать. Ты сразу можешь в примитивный тип превращать:
int valOrDefault = map.getOrDefault("I forgot my key", 0);
 
Назад
Сверху Снизу