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

Java 24(IntelliJ社区版)中如何为HashSet实现固定顺序以有序展示游戏成就

Java 24(IntelliJ社区版)中如何为HashSet实现固定顺序以有序展示游戏成就

我懂你现在的困扰:想用HashSet带来的高效查找特性,又希望游戏成就严格按照你定义的顺序(比如先金币类、再点击类,从低到高难度)展示,但HashSet本身就是无序且不保证遍历顺序的,所以你现在看到的成就列表顺序混乱很正常。下面给你两个既能保留HashSet高效性,又能实现固定展示顺序的解决方案,结合你的代码直接改就行:

方案一:用LinkedHashSet替代HashSet(最省心的方案)

LinkedHashSet是HashSet的子类,它会在HashSet的基础上用一个双向链表维护元素的插入顺序,也就是说你添加元素的顺序就是遍历的顺序,同时它的contains()、add()等核心方法的时间复杂度还是O(1),完全满足你要的高效性。

具体修改步骤:

  1. 在AchievementManager类里,把allAchievements的声明从HashSet改成LinkedHashSet:
import java.util.LinkedHashSet;

// 替换原有HashSet声明
LinkedHashSet<String> allAchievements = new LinkedHashSet<>();
  1. 调整GamePanel的openAchievementMenu方法里的遍历逻辑:
    原来你为了应对HashSet的无序用了Collections.reverse,现在LinkedHashSet已经能保留插入顺序了,直接遍历allAchievements就行,去掉反转的冗余代码:
// 删掉这段无效的反转代码
// java.util.List<String> reversedList = new java.util.ArrayList<>(achievementManager.allAchievements);
// Collections.reverse(reversedList);

// 直接遍历LinkedHashSet,就是你定义的顺序
for (String achievement : achievementManager.allAchievements) {
    boolean isUnlocked = achievementManager.unlockedAchievements.contains(achievement);
    achievementManager.createNewButton(achievement, isUnlocked);
}

这样遍历出来的顺序就是你初始化块里添加的顺序:coin10 → coin500 → coin1000000 → click50 → click250 → click1000,完全符合预期。

方案二:单独维护展示顺序列表(兼容原有HashSet)

如果你不想替换HashSet,也可以单独维护一个固定顺序的成就ID列表,用HashSet负责快速的存在性检查,用列表控制展示顺序:

具体修改步骤:

  1. 在AchievementManager里添加一个固定顺序的列表,同时用这个列表初始化allAchievements:
import java.util.Arrays;
import java.util.List;

// 固定展示顺序的列表,完全按照你想要的顺序定义
private List<String> achievementDisplayOrder = Arrays.asList(
    "coin10", "coin500", "coin1000000", "click50", "click250", "click1000"
);
// 用列表初始化HashSet,保留高效查找特性
HashSet<String> allAchievements = new HashSet<>(achievementDisplayOrder);
  1. 在GamePanel的openAchievementMenu里遍历这个顺序列表:
// 遍历固定顺序的列表,而不是无序的HashSet
for (String achievement : achievementManager.achievementDisplayOrder) {
    boolean isUnlocked = achievementManager.unlockedAchievements.contains(achievement);
    achievementManager.createNewButton(achievement, isUnlocked);
}

这样不管HashSet的内部顺序怎么变,展示顺序都由你定义的列表牢牢控制,同时allAchievements的高效查找特性也完全保留。

额外小提示:修复代码里的笔误

我注意到你achievementCheck方法里有个容易忽略的bug:

// 这里判断的是"coins1000000"(多了个s),和解锁的ID不匹配
if(stats.getMoney() >= 1000000 && !unlockedAchievements.contains("coins1000000")){
    unlock("coin1000000");
}

会导致100万金币的成就永远无法触发,记得把判断里的ID改成"coin1000000"哦~


备注:内容来源于stack exchange,提问作者user27209652

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 20:09:51