Android使用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
相关产品推荐
相关产品推荐

