我正在为minecraft服务器开发两个api,一个代理和一个spigot,当玩家连接时,代理API从数据库中获取玩家,然后将其发送到redis,然后api spigot将查找播放器在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的key是玩家的uuid,value是JSON序列化的用户类,API为Gson 我最近知道 Gson 为了反序列化,创建了自己的空构造函数,并通过反射填充字段,这是我不想要的,因为我是在我的构造函数中将 User 放入映射中的。因此,我创建了自己的 TypeAdapter 来实现 JsonDeserializer,以便运行构造函数。它有效,构造函数执行得很好,但用户没有放入 map 中!因此,每次我创建 User#get 时,它都会运行 fetchUser,最终会因为请求太多而崩溃。我将我的类(class)放入粘贴箱中供您观看。 (抱歉,如果这不是方法,这是我第一次在 stackoverflow 上发帖,抱歉我的英语,我是法国人,我使用谷歌翻译)
用户.java > https://pastebin.com/4ta4XDqX
RedisAPI.java > https://pastebin.com/GjWPUf4m
Serializer.java > https://pastebin.com/k6g1KYYF
UserDeserializer.java > https://pastebin.com/0LF7trSR
提前谢谢您。
最佳答案
Returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key.
所以,它根本不会给 map 添加任何值(value)。无论 UUID
是否存在于 map 中,您也始终会急切地执行 User::fetchUser
方法。
听起来你需要Map::computeIfAbsent
相反,其中:
If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.
即
public static User get(UUID uuid) {
return users.computeIfAbsent(uuid, User::fetchUser);
}
仅当在 map 中未找到 UUID
时才会执行 User::fetchUser
。
关于Java,当我将用户放入 map 时,它不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55313650/