Java,当我将用户放入地图时,它无法正常工作

时间:2019-03-23 12:20:21

标签: java dictionary hashmap gson

我正在为minecraft服务器开发两个api,一个代理和一个插头,当玩家连接时,代理API会在数据库上获取玩家,然后在redis上发送它,然后api插头会寻找播放器上的redis,然后将其保存在Map中,这就是问题所在,我有一个类似的“ User#get”方法:

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

和这样的“ User#fetchUser”:

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

键redis是播放器的uuid,值是使用api Gson以JSON序列化的用户类。 最近,我知道Gson要反序列化,创建了自己的空构造函数,并通过反射填充了字段,而这是我不希望的,因为我是在构造函数中将User放入地图的。因此,我创建了自己的实现JsonDeserializer的TypeAdapter,以运行构造函数。它工作正常,构造函数执行良好,但用户未放在地图中!因此,每次我创建一个User#get时,它都会运行fetchUser,并且由于请求过多而最终崩溃。我正在将我的课程放在粘贴框中供您观看。 (很抱歉,这不是这样做的方法,这是我第一次在stackoverflow上发帖,对不起我的英语,我是法语,我使用谷歌翻译)

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 个答案:

答案 0 :(得分:4)

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