我正在为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
谢谢。
答案 0 :(得分:4)
返回指定键所映射的值,如果此映射不包含键的映射关系,则返回defaultValue。
因此,它根本不会向地图添加任何值。无论地图中是否存在User::fetchUser
,您也总是热切地执行UUID
方法。
听起来您需要Map::computeIfAbsent
来代替,
如果指定的键尚未与某个值关联(或已映射为null),则尝试使用给定的映射函数计算其值,除非为null,否则将其输入到此映射中。
即
public static User get(UUID uuid) {
return users.computeIfAbsent(uuid, User::fetchUser);
}
仅在尚未在地图中找到User::fetchUser
的情况下执行UUID
。