Java HashMap密钥的随机访问

Java HashMap密钥的随机访问,java,hashmap,key,random-access,Java,Hashmap,Key,Random Access,我需要随机访问HashMap中的密钥。现在,我正在HashMap的keySet()返回的集上使用集的toArray()方法,并将其转换为字符串[](我的键是字符串)。然后我使用Random选择字符串数组中的一个随机元素 public String randomKey() { String[] keys = (String[]) myHashMap.keySet().toArray(); Random rand = new Random(); return keyring[

我需要随机访问HashMap中的密钥。现在,我正在HashMap的keySet()返回的集上使用集的toArray()方法,并将其转换为字符串[](我的键是字符串)。然后我使用Random选择字符串数组中的一个随机元素

public String randomKey() {
    String[] keys = (String[]) myHashMap.keySet().toArray();
    Random rand = new Random();
    return keyring[rand.nextInt(keyring.length)];
}
似乎应该有一种更优雅的方式来做这件事!
我读过下面的帖子,但它似乎比我现在做的方式更复杂。如果下面的解决方案更好,为什么会这样?

为什么不使用
Collections.shuffle
方法,保存到一个变量中,然后根据需要从顶部弹出一个


HashMap中没有一种工具可以在不知道密钥的情况下返回条目,因此,如果您只想使用该类,那么您拥有的解决方案可能与其他解决方案一样好

但是请记住,您实际上并不局限于使用
HashMap

如果您阅读此集合的频率远高于编写此集合的频率,则可以创建自己的类,该类包含映射的
HashMap
,以及允许随机访问的不同键集合(如
向量

这样,您就不会在每次读取时将映射转换为集合或数组,而只在必要时(从集合中添加或删除项目)才会发生

不幸的是,
向量
允许具有相同值的多个键,因此在插入时必须防止出现这种情况(以确保选择随机键时的公平性)。这将增加插入的成本

删除也会增加成本,因为您必须搜索要从向量中删除的项目

我不确定是否有一个简单的单一收集为这个目的。如果您想全力以赴,您可以使用当前的
HashMap
、键的
Vector
,以及另一个
HashMap
将键映射到向量索引

这样,所有操作(插入、删除、更改、随机获取)在时间上都是O(1),在时间上效率很高,在空间上效率可能更低:-)

或者有一种折衷的解决方案,它仍然使用包装器,但在插入、更改或删除密钥时创建一个长寿命的字符串数组。这样,您只需要在需要时创建阵列,并且仍然可以摊销成本。然后,您的类使用hashmap进行有效的键访问,使用数组进行随机选择

而且变化很小。您已经有了创建数组的代码,只需创建包装器类,它从
HashMap
中提供您所需的任何内容(并且只需将大多数调用传递到
HashMap
),再加上一个额外的函数(使用数组)即可获得随机键


现在,如果性能实际上是一个问题,我只考虑使用这些方法。您可以花费无数的时间以无关紧要的方式加快代码的速度:-)


如果您所拥有的足够快,就可以了。

您可以避免将整个键集复制到临时数据结构中,方法是首先获取大小,选择随机索引,然后在键集上迭代适当的次数


这段代码需要同步以避免并发修改。

这还不错。只需三行代码,并以一种易于使用/易于理解的方法整齐地打包。但您应该首先检查空映射。我没有读到
Random
变量应保持在方法外部,否则上述代码将不会提供很好的随机性吗?quote:如果使用相同的种子创建两个随机实例,并且对每个实例进行相同的方法调用序列,则它们将生成并返回相同的数字序列。@MohamedEl Beltagy,我正在为CS2类进行马尔可夫文本生成赋值。我从源文本中出现的每个长度为k的字符串中生成一个键。与该键对应的值是源文本中该字符串每次出现后的所有字符(带有重复字符)的字符串。要生成类似随机源的文本,请从随机键开始,将其与字符串中的随机字符连接,更新种子,使其包含k个字符,然后重复。当seed/key在地图中没有值时,就会出现问题,这就需要我随机选择另一个seed/key.construct,但对于大型地图来说,它似乎太慢了。不需要把所有的人都洗牌,只选一个。我不知道OP说他会选哪一个。我建议保存洗牌后的列表,以便再次使用。好的,如果地图没有更改,并且您希望重复获得一个随机键,那么这将很好。如果需要,您甚至可以使用您的方法获得“选择而不替换”。