有没有办法在 Java 中随机获取 HashMap 的值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/929554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to get the value of a HashMap randomly in Java?
提问by Varuna
Is there a way to get the value of a HashMap randomly in Java?
有没有办法在 Java 中随机获取 HashMap 的值?
采纳答案by Tom Jefferys
This works:
这有效:
Random generator = new Random();
Object[] values = myHashMap.values().toArray();
Object randomValue = values[generator.nextInt(values.length)];
If you want the random value to be a type other than an Object
simply add a cast to the last line. So if myHashMap
was declared as:
如果您希望随机值不是Object
简单的类型,只需在最后一行添加一个强制转换。所以如果myHashMap
被声明为:
Map<Integer,String> myHashMap = new HashMap<Integer,String>();
The last line can be:
最后一行可以是:
String randomValue = (String) values[generator.nextInt(value.length)];
The below doesn't work, Set.toArray()
always returns an array of Object
s, which can't be coerced into an array of Map.Entry
.
下面的不起作用,Set.toArray()
总是返回一个Object
s的数组,它不能被强制转换为Map.Entry
.
Random generator = new Random();
Map.Entry[] entries = myHashMap.entrySet().toArray();
randomValue = entries[generator.nextInt(entries.length)].getValue();
回答by Alistair Evans
It depends on what your key is - the nature of a hashmap doesn't allow for this to happen easily.
这取决于您的密钥是什么 - 哈希图的性质不允许这种情况轻易发生。
The way I can think of off the top of my head is to select a random number between 1 and the size of the hashmap, and then start iterating over it, maintaining a count as you go - when count is equal to that random number you chose, that is your random element.
我能想到的方法是在 1 和哈希图的大小之间选择一个随机数,然后开始对其进行迭代,随时保持计数 - 当计数等于该随机数时选择了,那是你的随机元素。
回答by Peter Stuifzand
Generate a random number between 0 and the number of keys in your HashMap
. Get the key at the random number. Get the value from that key.
生成一个介于 0 和HashMap
. 获取随机数处的密钥。从该键中获取值。
Pseudocode:
伪代码:
int n = random(map.keys().length());
String key = map.keys().at(n);
Object value = map.at(key);
If it's hard to implement this in Java, then you could create and array from this code using the toArray()
function in Set
.
如果很难在Java中实现这一点,那么你可以创建并使用此代码阵列toArray()
中的功能Set
。
Object[] values = map.values().toArray(new Object[map.size()]);
Object random_value = values[random(values.length)];
I'm not really sure how to do the random number.
我不太确定如何做随机数。
回答by coobird
Since the requirements only asks for a random value from the HashMap
, here's the approach:
由于要求只要求从 中获取随机值HashMap
,因此方法如下:
- The
HashMap
has avalues
method which returns aCollection
of the values in the map. - The
Collection
is used to create aList
. - The
size
method is used to find the size of theList
, which is used by theRandom.nextInt
method to get a random index of theList
. - Finally, the value is retrieved from the
List
get
method with the random index.
- 所述
HashMap
具有values
返回的方法Collection
中的值的在地图中。 - 将
Collection
用于创建一个List
。 - 该
size
方法用于查找的大小List
,这是使用的Random.nextInt
方法得到的随机指数List
。 - 最后,从
List
get
具有随机索引的方法中检索该值。
Implementation:
执行:
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Hello", 10);
map.put("Answer", 42);
List<Integer> valuesList = new ArrayList<Integer>(map.values());
int randomIndex = new Random().nextInt(valuesList.size());
Integer randomValue = valuesList.get(randomIndex);
The nice part about this approach is that all the methods are generic-- there is no need for typecasting.
这种方法的好处在于所有方法都是通用的——不需要类型转换。
回答by MH114
Here is an example how to use the arrays approach described by Peter Stuifzand, also through the values()
-method:
下面是一个如何使用 Peter Stuifzand 描述的数组方法的例子,也是通过values()
- 方法:
// Populate the map
// ...
Object[] keys = map.keySet().toArray();
Object[] values = map.values().toArray();
Random rand = new Random();
// Get random key (and value, as an example)
String randKey = keys[ rand.nextInt(keys.length) ];
String randValue = values[ rand.nextInt(values.length) ];
// Use the random key
System.out.println( map.get(randKey) );
回答by kctang
i really don't know why you want to do this... but if it helps, i've created a RandomMap that automatically randomizes the values when you call values(), then the following runnable demo application might do the job...
我真的不知道你为什么要这样做......但如果它有帮助,我已经创建了一个 RandomMap,当你调用 values() 时它会自动随机化这些值,那么下面的可运行演示应用程序可能会完成这项工作.. .
package random;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
Map hashMap = makeHashMap();
// you can make any Map random by making them a RandomMap
// better if you can just create the Map as a RandomMap instead of HashMap
Map randomMap = new RandomMap(hashMap);
// just call values() and iterate through them, they will be random
Iterator iter = randomMap.values().iterator();
while (iter.hasNext()) {
String value = (String) iter.next();
System.out.println(value);
}
}
private static Map makeHashMap() {
Map retVal;
// HashMap is not ordered, and not exactly random (read the javadocs)
retVal = new HashMap();
// TreeMap sorts your map based on Comparable of keys
retVal = new TreeMap();
// RandomMap - a map that returns stuff randomly
// use this, don't have to create RandomMap after function returns
// retVal = new HashMap();
for (int i = 0; i < 20; i++) {
retVal.put("key" + i, "value" + i);
}
return retVal;
}
}
/**
* An implementation of Map that shuffles the Collection returned by values().
* Similar approach can be applied to its entrySet() and keySet() methods.
*/
class RandomMap extends HashMap {
public RandomMap() {
super();
}
public RandomMap(Map map) {
super(map);
}
/**
* Randomize the values on every call to values()
*
* @return randomized Collection
*/
@Override
public Collection values() {
List randomList = new ArrayList(super.values());
Collections.shuffle(randomList);
return randomList;
}
}
回答by banjollity
Should you need to draw futher values from the map without repeating any elements you can put the map into a List and then shuffle it.
如果您需要在不重复任何元素的情况下从地图中绘制更多值,您可以将地图放入一个列表中,然后对其进行洗牌。
List<Object> valuesList = new ArrayList<Object>(map.values());
Collections.shuffle( valuesList );
for ( Object obj : valuesList ) {
System.out.println( obj );
}
回答by Neil Coffey
A good answer depends slightly on the circumstances, in particular how often you need to get a random key for a given map (N.B. the technique is essentially the same whether you take key or value).
一个好的答案略取决于具体情况,特别是您需要为给定地图获取随机密钥的频率(注意,无论您使用密钥还是值,该技术本质上都是相同的)。
- If you need various random keysfrom a given map, without the map changingin between getting the random keys, then use the random sampling methodas you iterate through the key set. Effectively what you do is iterate over the set returned by keySet(), and on each item calculate the probability of wanting to take that key, given how many you will need overall and the number you've taken so far. Then generate a random number and see if that number is lower than the probability. (N.B. This method will always work, even if you only need 1 key; it's just not necessarily the most efficient way in that case.)
- The keys in a HashMap are effectively in pseudo-random order already. In an extreme case where you will only ever need one random keyfor a given possible map, you could even just pull out the first element of the keySet().
- In other cases(where you either need multiple possible random keys for a given possible map, or the map will change between you taking random keys), you essentially have to create or maintain an array/listof the keys from which you select a random key.
- 如果您需要 给定映射中的各种随机键,而映射在获取随机键之间没有变化,则在迭代键集时使用随机采样方法。您所做的实际上是迭代 keySet() 返回的集合,并在每个项目上计算想要获取该键的概率,考虑到您总共需要多少以及到目前为止您已获取的数量。然后生成一个随机数,看看这个数是否低于概率。(注意此方法将始终有效,即使您只需要 1 个密钥;在这种情况下,它不一定是最有效的方法。)
- HashMap 中的键已经有效地按伪随机顺序排列。在极端情况下,对于给定的可能映射,您只需要一个随机键,您甚至可以取出keySet()的第一个元素。
- 在其他情况下(对于给定的可能映射,您需要多个可能的随机键,或者在您获取随机键之间映射会发生变化),您基本上必须 创建或维护一个键的数组/列表,您可以从中选择一个随机键钥匙。
回答by Kalisky
Usually you do not really want a randomvalue but rather just anyvalue, and then it's nice doing this:
通常你并不真正想要一个随机值,而是任何值,然后这样做很好:
Object selectedObj = null;
for (Object obj : map.values()) {
selectedObj = obj;
break;
}
回答by Quonux
Converting it to an array and then getting the value is too slow when its in the hot path.
当它在热路径中时,将其转换为数组然后获取值太慢了。
so get the set (either the key or keyvalue set) and do something like:
所以获取集合(键或键值集)并执行以下操作:
public class SetUtility {
public static<Type> Type getRandomElementFromSet(final Set<Type> set, Random random) {
final int index = random.nextInt(set.size());
Iterator<Type> iterator = set.iterator();
for( int i = 0; i < index-1; i++ ) {
iterator.next();
}
return iterator.next();
}