You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Discord用户IdLong存储并检索关联数据?

Discord JDA 用户数据存储解决方案

一、内存中高效存储与检索

别用ArrayList<ArrayList<Long>>了,直接用键值对集合(Map),把用户ID作为键(Long类型),用户的相关数据作为值。这样通过用户ID可以直接定位到对应数据,时间复杂度是O(1),比遍历ArrayList高效太多。

实现步骤:

  1. 定义一个简单的数据类封装用户信息(比如初始值和后续新增数据):
public class UserData {
    private long initialValue; // 初始值1L
    // 可按需添加其他long型字段
    // 构造方法、getter/setter
    public UserData(long initialValue) {
        this.initialValue = initialValue;
    }

    public long getInitialValue() {
        return initialValue;
    }

    public void setInitialValue(long initialValue) {
        this.initialValue = initialValue;
    }
    // 新增字段的getter/setter同理
}
  1. 初始化全局Map存储用户数据:
private Map<Long, UserData> userDataMap = new HashMap<>();
  1. 处理;create指令时存入数据:
// 指令监听方法示例
public void onCommand(MessageReceivedEvent event) {
    String message = event.getMessage().getContentRaw();
    if (message.startsWith(";create")) {
        long userId = event.getAuthor().getIdLong();
        if (!userDataMap.containsKey(userId)) {
            userDataMap.put(userId, new UserData(1L));
            event.getChannel().sendMessage("数据创建成功!").queue();
        } else {
            event.getChannel().sendMessage("你已创建过数据!").queue();
        }
    }
}
  1. 检索指定用户的初始值:
long targetUserId = 123456789L; // 目标用户ID
if (userDataMap.containsKey(targetUserId)) {
    long initialValue = userDataMap.get(targetUserId).getInitialValue();
    // 后续逻辑处理
}

二、文件持久化存储(解决Bot重启数据丢失问题)

方案1:JSON格式存储(最适合自学开发者)

用JSON序列化整个userDataMap,读写操作简单,无需手动处理行定位。推荐用Google的Gson库实现:

  1. 添加Gson依赖(Maven示例):
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>
  1. 实现保存与加载方法:
private static final String DATA_FILE = "user_data.json";
private Gson gson = new GsonBuilder().setPrettyPrinting().create();

// 保存数据到文件
public void saveUserData() {
    try (FileWriter writer = new FileWriter(DATA_FILE)) {
        gson.toJson(userDataMap, writer);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 从文件加载数据
public void loadUserData() {
    File file = new File(DATA_FILE);
    if (!file.exists()) return;
    try (FileReader reader = new FileReader(file)) {
        Type mapType = new TypeToken<Map<Long, UserData>>(){}.getType();
        userDataMap = gson.fromJson(reader, mapType);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  1. 使用时机:
  • Bot启动时调用loadUserData()加载数据
  • 每次修改数据(如;create执行后)调用saveUserData()保存
  • 也可定时保存,比如用ScheduledExecutorService每5分钟执行一次保存操作

方案2:自定义文本行存储(坚持每行存用户数据)

如果一定要用每行存储(格式示例:用户ID:初始值:其他数据),可按以下方式实现查找与修改:

  1. 查找指定用户ID的行:
public String findUserLine(long userId) {
    try (BufferedReader reader = new BufferedReader(new FileReader("user_data.txt"))) {
        String line;
        while ((line = reader.readLine()) != null) {
            String[] parts = line.split(":");
            if (parts.length > 0 && Long.parseLong(parts[0]) == userId) {
                return line;
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}
  1. 修改用户数据(需读写整个文件):
public void updateUserData(long userId, long newInitialValue) {
    List<String> lines = new ArrayList<>();
    boolean isUserExist = false;
    // 读取所有行
    try (BufferedReader reader = new BufferedReader(new FileReader("user_data.txt"))) {
        String line;
        while ((line = reader.readLine()) != null) {
            String[] parts = line.split(":");
            if (parts.length > 0 && Long.parseLong(parts[0]) == userId) {
                // 修改该行数据
                lines.add(userId + ":" + newInitialValue + ":" + (parts.length > 2 ? parts[2] : ""));
                isUserExist = true;
            } else {
                lines.add(line);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 新用户则添加行
    if (!isUserExist) {
        lines.add(userId + ":" + newInitialValue + ":");
    }
    // 重新写入文件
    try (BufferedWriter writer = new BufferedWriter(new FileWriter("user_data.txt"))) {
        for (String line : lines) {
            writer.write(line);
            writer.newLine();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

此方案适合简单场景,但数据量大时效率低于JSON方案,因为每次修改都需读写整个文件。


内容的提问来源于stack exchange,提问作者Marvel Charles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:40:32