首页 > 解决方案 > Java,当我将用户放入地图时,它不起作用

问题描述

我正在为我的世界服务器、代理和 spigot 开发两个 api,当玩家连接时,代理 API 会在数据库中获取玩家,然后将其发送到 redis,然后 api spigot 将在 redis 上查找玩家,并将其保存在地图中,这就是问题所在,我有一个像这样的“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,为了反序列化,创建了自己的空构造函数,并通过反射填充字段,我不想要,因为它是在我的构造函数中,我将用户放在地图中。所以我创建了自己的实现 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

先感谢您。

标签: javadictionaryhashmapgson

解决方案


Map::getOrDefault做:

返回指定键映射到的值,如果此映射不包含该键的映射,则返回 defaultValue。

因此,它根本不会为地图增加任何价值。您也总是急切地执行该User::fetchUser方法,无论该方法是否UUID存在于地图中。

听起来您需要Map::computeIfAbsent的是:

如果指定的键尚未与值关联(或映射为 null),则尝试使用给定的映射函数计算其值并将其输入到此映射中,除非为 null。

IE

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

Where仅在未在地图中找到User::fetchUser时才执行。UUID


推荐阅读