【问题标题】:How to shuffle a Hashtable in java如何在java中洗牌一个哈希表
【发布时间】:2019-05-09 11:41:13
【问题描述】:

我在一个类中有一个构造函数,我在其中初始化一个哈希表,由一个整数和一个字符串列表组成。我用从 0 到任何需要的数字填充键,它们对应的值是我事先在构造函数中创建的向量。我需要的是随机重新排列它们(只是以任何可能的方式随机排列它们),这样当我使用 getQuest() 时,我会得到一个随机键值对,它恰好位于哈希表的最后一个位置并将其删除同时。

public class Quest {

private Hashtable<Integer, List<String>> quests;

public Quest()
{
    this.quests = new Hashtable<>();
    List<String> mushrooms = new Vector<>();
    mushrooms.add("Choose a mushroom, but be careful not to be poisoned");
    mushrooms.add("mushroom1");
    mushrooms.add("mushroom2");
    mushrooms.add("mushroom3");
    List<String> weapons = new Vector<>();
    weapons.add("Choose a weapon that will help you survive");
    weapons.add("knife");
    weapons.add("rifle");
    weapons.add("sword");
    this.quests.put(0, mushrooms);
    this.quests.put(1, weapons);
}

public List<String> getQuest()
{
    return quests.remove(quests.size());

}
}

另外,如果这不是一个好主意,最好使用 rand 或类似的东西并从哈希表中的某处获取随机对以返回(当然也要删除它)。

【问题讨论】:

  • 旁注:HashtableVector 自 Java 1.3 以来已过时。考虑改用HashMapArrayList

标签: java class dictionary hashtable shuffle


【解决方案1】:

您不会“打乱”HashtableMap - 元素没有排序。

也就是说,iterator 通常每次都会返回相同的顺序,因此为了改变它,将键放入 ArrayList 并在其上使用 Collections.shuffle。遍历该混洗列表并通过它们的键访问表/映射中的元素。

【讨论】:

  • @Krease 只是出于好奇,因为 HashTable 使用散列,元素将根据那里的键的散列码存储。那么我们不能重写hashcode方法来实现不同的顺序吗?
  • @Gaurav - 不要试图覆盖 hashCode 来控制 HashMap 迭代顺序。从理论上讲,可能,但这是任何理智的开发人员都不应该做的极其脆弱的代码。 (hashCode 的实现具有巨大的额外复杂性,紧密依赖于HashMap 迭代的确切实现,受存储桶大小调整的影响,意外破坏equals 合约的可能性很高,可能会增加哈希冲突等)。为清楚起见重复:不要尝试覆盖 hashCode 来控制 HashMap 迭代顺序
【解决方案2】:

使用列表而不是哈希表,并删除随机索引处的项目。

另外,如果按照你的方式做,这一行:

return quests.remove(quests.size());

应该是

return quests.remove(quests.size()-1);

您可能还想检查 quests.size() > 0...

【讨论】:

  • 是的,这可能是个好主意。我一开始的计划和现在有点不同,我有点搞砸了我的逻辑。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-01-08
  • 2012-05-30
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 2014-03-30
相关资源
最近更新 更多