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

Android使用SharedPreferences存储前五名玩家高分的报错问题

解决SharedPreferences存储前五名高分的类型错误问题

嘿,我来帮你搞定这个存储高分的问题!你遇到的错误核心原因很明确:SharedPreferences的putStringSet()方法只接受Set<String>类型的参数,但你传了一个String[][]二维数组,类型完全不匹配,所以编译器直接报错了。

SharedPreferences本身不支持直接存储数组或二维数组,它只认基本数据类型、String和Set这类简单结构。所以我们需要把玩家的姓名+分数转换成它能接受的格式,同时还要实现“保留前五名”的逻辑。

下面给你两种可行的解决方案,按需选择:

方案一:字符串拼接(简单直接)

把每个玩家的姓名和分数用一个分隔符(比如|)拼接成单个字符串,再把这些字符串放到Set里存储。步骤如下:

完整存储代码

public static void setHighScore(Context context, String name, int score) {
    // 1. 获取SharedPreferences实例
    SharedPreferences prefs = context.getSharedPreferences("HighScorePrefs", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();

    // 2. 读取现有高分数据(如果没有就用空Set)
    Set<String> existingScores = prefs.getStringSet("top_five_scores", new HashSet<>());
    List<String> scoreList = new ArrayList<>(existingScores);

    // 3. 添加新的玩家数据(姓名|分数)
    String newScoreEntry = name + "|" + score;
    scoreList.add(newScoreEntry);

    // 4. 按分数从高到低排序
    Collections.sort(scoreList, new Comparator<String>() {
        @Override
        public int compare(String entry1, String entry2) {
            // 拆分字符串获取分数
            int score1 = Integer.parseInt(entry1.split("\\|")[1]);
            int score2 = Integer.parseInt(entry2.split("\\|")[1]);
            // 降序排列,所以用score2 - score1
            return Integer.compare(score2, score1);
        }
    });

    // 5. 只保留前五名
    if (scoreList.size() > 5) {
        scoreList = scoreList.subList(0, 5);
    }

    // 6. 把List转回Set,存入SharedPreferences
    Set<String> updatedScores = new HashSet<>(scoreList);
    editor.putStringSet("top_five_scores", updatedScores);
    editor.apply(); // 异步提交,也可以用commit()同步提交
}

读取高分的代码

public static List<Map<String, Object>> getHighScores(Context context) {
    SharedPreferences prefs = context.getSharedPreferences("HighScorePrefs", Context.MODE_PRIVATE);
    Set<String> scoreSet = prefs.getStringSet("top_five_scores", new HashSet<>());
    List<String> scoreList = new ArrayList<>(scoreSet);
    List<Map<String, Object>> result = new ArrayList<>();

    // 再次排序(因为Set是无序的,读取后需要重新排序)
    Collections.sort(scoreList, new Comparator<String>() {
        @Override
        public int compare(String entry1, String entry2) {
            int score1 = Integer.parseInt(entry1.split("\\|")[1]);
            int score2 = Integer.parseInt(entry2.split("\\|")[1]);
            return Integer.compare(score2, score1);
        }
    });

    // 拆分字符串,转换成易读的结构
    for (String entry : scoreList) {
        String[] parts = entry.split("\\|");
        Map<String, Object> player = new HashMap<>();
        player.put("name", parts[0]);
        player.put("score", Integer.parseInt(parts[1]));
        result.add(player);
    }
    return result;
}

方案二:JSON序列化(更稳妥,适合复杂数据)

如果担心玩家姓名里出现分隔符(比如|)导致拆分错误,或者以后要扩展玩家数据(比如添加时间),用JSON序列化会更靠谱。我们可以定义一个Player类,用Gson把玩家列表转成JSON字符串存储。

步骤1:添加Gson依赖(Android项目)

在build.gradle(Module)里添加:

dependencies {
    implementation 'com.google.code.gson:gson:2.10.1'
}

步骤2:定义Player类

public class Player {
    public String name;
    public int score;

    public Player() {} // 必须有默认构造函数,Gson需要

    public Player(String name, int score) {
        this.name = name;
        this.score = score;
    }
}

步骤3:存储高分的代码

public static void setHighScore(Context context, String name, int score) {
    SharedPreferences prefs = context.getSharedPreferences("HighScorePrefs", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();
    Gson gson = new Gson();

    // 读取现有玩家列表
    String existingJson = prefs.getString("top_five_players", "[]");
    Type playerListType = new TypeToken<List<Player>>(){}.getType();
    List<Player> playerList = gson.fromJson(existingJson, playerListType);

    // 添加新玩家
    playerList.add(new Player(name, score));

    // 按分数降序排序
    Collections.sort(playerList, new Comparator<Player>() {
        @Override
        public int compare(Player p1, Player p2) {
            return Integer.compare(p2.score, p1.score);
        }
    });

    // 保留前五名
    if (playerList.size() > 5) {
        playerList = playerList.subList(0, 5);
    }

    // 转成JSON字符串存储
    String updatedJson = gson.toJson(playerList);
    editor.putString("top_five_players", updatedJson);
    editor.apply();
}

步骤4:读取高分的代码

public static List<Player> getHighScores(Context context) {
    SharedPreferences prefs = context.getSharedPreferences("HighScorePrefs", Context.MODE_PRIVATE);
    String json = prefs.getString("top_five_players", "[]");
    Type playerListType = new TypeToken<List<Player>>(){}.getType();
    List<Player> playerList = new Gson().fromJson(json, playerListType);

    // 确保排序正确
    Collections.sort(playerList, new Comparator<Player>() {
        @Override
        public int compare(Player p1, Player p2) {
            return Integer.compare(p2.score, p1.score);
        }
    });

    return playerList;
}

两种方案各有优劣:方案一不用加额外依赖,适合简单场景;方案二更灵活,扩展性强,不容易出格式冲突问题。你可以根据自己的需求选择~

内容的提问来源于stack exchange,提问作者ivan franken

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:23:16