[英]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.