繁体   English   中英

随机访问 HashMap 个密钥

[英]Random access for HashMap keys

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

public String randomKey() {
    String[] keys = (String[]) myHashMap.keySet().toArray();
    Random rand = new Random();
    return keyring[rand.nextInt(keyring.length)];
}

似乎应该有一种更优雅的方式来做到这一点,我已经阅读了以下帖子。 但它似乎比我这样做的方式更令人费解,如果以下解决方案更好? 为什么? 从 Java 中的 Map 中选择随机键和值集

HashMap没有设施可在不知道键的情况下返回条目,因此,如果您只想使用该类,那么所拥有的解决方案可能与任何解决方案一样好。

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

如果你要来读这个集合的次数远远多于写它,你可以创建自己的类,它包含一个HashMap映射的和不同的集合,它允许随机访问(如按键的Vector )。

这样,您就不会在每次阅读时都将地图转换为集合然后转换为数组的成本它只会在必要时发生(在集合中添加或删除项目)。

不幸的是, Vector允许多个具有相同值的键,因此在插入时您必须对此加以防范(以确保选择随机键时的公平性)。 这将增加插入成本。

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

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

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

或者有一种中途解决方案仍然使用包装器,但是每当您插入,更改或删除键时都会创建一个长寿命的字符串数组。 这样,您仅在需要时创建阵列,而且仍可以摊销成本。 然后,您的类使用哈希图通过键进行有效访问,并使用数组进行随机选择。

而且那里的变化很小。 您已经具有创建数组的代码,只需创建包装器类即可提供HashMap所需的任何内容(并将大多数调用传递HashMap )以及一个额外的函数来获取随机密钥(使用数组) )。


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

如果您拥有的足够快,那就没问题了。

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

http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#shuffle(java.util.List)

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

该代码将需要同步以避免并发修改。

如果您真的只想要集合中的任何元素,这会很好用。

String s = set.iterator().next();

如果不确定集合中是否有元素,请使用:

String s;
Iterator<String> it = set.iterator();
if (it.hasNext()) {
    s = it.next();
}
else {
    // set was empty
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM