Java, когда я помещаю своего пользователя в карту, он не работает - PullRequest
2 голосов
/ 23 марта 2019

Я разрабатываю два API для сервера Minecraft, прокси и Spigot, когда игрок подключается, API прокси-сервера выбирает игрока в базе данных, затем отправляет его на Redis, затем SpiGot API будет искатьигрок на Redis, и сохранить его на карте, и вот в чем проблема, у меня есть метод «Пользователь # получить», как это:

public static User get(UUID uuid) {
    return users.getOrDefault(uuid, fetchUser(uuid));
}

и «Пользователь # fetchUser», как это:

private static User fetchUser(UUID uuid) {
    return Main.instance.getRedisAPI().get(uuid.toString(), User.class);
}

Ключ redis - это uuid проигрывателя, а значение - это пользовательский класс, сериализованный в JSON, с API Gson, который я недавно знал, что Gson для десериализации создал свой собственный пустой конструктор изаполнил поля отражением, которое мне не нужно, потому что именно в моем конструкторе я поместил пользователя на карту.Поэтому я создал свой собственный TypeAdapter, который реализует JsonDeserializer, чтобы запустить конструктор.это работает, конструктор хорошо выполнен, но пользователь не помещен в карту!Таким образом, каждый раз, когда я делаю User # get, он запускает fetchUser и в итоге вылетает, потому что слишком много запросов.Я кладу свои занятия в пастбище, чтобы вы могли посмотреть.(извините, если это не так, я впервые пишу на stackoverflow, и извините за мой английский, я французский и использую перевод Google)

User.java> https://pastebin.com/4ta4XDqX
RedisAPI.java> https://pastebin.com/GjWPUf4m
Serializer.java> https://pastebin.com/k6g1KYYF
UserDeserializer.java> https://pastebin.com/0LF7trSR

Заранее спасибо.

1 Ответ

4 голосов
/ 23 марта 2019

Map::getOrDefault делает:

Возвращает значение, которому сопоставлен указанный ключ, или defaultValue, если эта карта не содержит сопоставления для ключа.

Таким образом, это не добавляет никакой ценности к карте вообще.Вы также всегда с энтузиазмом выполняете метод User::fetchUser, независимо от того, существует ли UUID на карте или нет.

Похоже, вам нужно Map::computeIfAbsent вместо этого, что:

Если указанный ключ еще не связан со значением (или сопоставлен со значением NULL), пытается вычислить его значение с использованием заданной функции сопоставления и вводит его в эту карту, если только не NULL.

т.е.

public static User get(UUID uuid) {
    return users.computeIfAbsent(uuid, User::fetchUser);
}

Где User::fetchUser выполняется только в том случае, если UUID не был найден на карте уже.

...