有没有办法在Java中随机获取HashMap的值?
答案 0 :(得分:50)
这有效:
Random generator = new Random();
Object[] values = myHashMap.values().toArray();
Object randomValue = values[generator.nextInt(values.length)];
如果您希望随机值为Object
以外的类型,只需将转换添加到最后一行。因此,如果myHashMap
被声明为:
Map<Integer,String> myHashMap = new HashMap<Integer,String>();
最后一行可以是:
String randomValue = (String) values[generator.nextInt(value.length)];
以下不起作用,Set.toArray()
始终返回Object
个数组,但不能强制转换为Map.Entry
数组。
Random generator = new Random();
Map.Entry[] entries = myHashMap.entrySet().toArray();
randomValue = entries[generator.nextInt(entries.length)].getValue();
答案 1 :(得分:30)
由于要求只要求HashMap
中的随机值,这就是方法:
HashMap
有一个values
方法,可以在地图中返回Collection
个值。Collection
用于创建List
。size
方法用于查找List
的大小,Random.nextInt
方法使用该方法获取List
的随机索引。List
get
方法检索该值。实现:
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);
关于这种方法的好处是所有方法都是generic - 不需要进行类型转换。
答案 2 :(得分:10)
如果您需要从地图中绘制更多的值而不重复任何元素,您可以将地图放入List中,然后将其随机播放。
List<Object> valuesList = new ArrayList<Object>(map.values());
Collections.shuffle( valuesList );
for ( Object obj : valuesList ) {
System.out.println( obj );
}
答案 3 :(得分:3)
生成介于0和HashMap
中键数之间的随机数。获取随机数的密钥。从该密钥中获取值。
<强>伪代码强>:
int n = random(map.keys().length());
String key = map.keys().at(n);
Object value = map.at(key);
如果在Java中很难实现这一点,那么您可以使用toArray()
中的Set
函数从此代码创建和数组。
Object[] values = map.values().toArray(new Object[map.size()]);
Object random_value = values[random(values.length)];
我不确定如何做随机数。
答案 4 :(得分:1)
一个好的答案在很大程度上取决于具体情况,特别是你需要为给定地图获取一个随机密钥的频率(N.B.无论你采用密钥还是值,技术基本相同)。
答案 5 :(得分:1)
将其转换为数组,然后在热路径中获取值太慢。
所以得到集合(键或键值集)并执行以下操作:
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();
}
答案 6 :(得分:0)
以下是如何使用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) );
答案 7 :(得分:0)
我真的不知道你为什么要这样做...但如果它有帮助,我创建了一个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;
}
}
答案 8 :(得分:0)
通常你不是真的想要一个随机值,而只是任何值,然后这样做很好:
Object selectedObj = null;
for (Object obj : map.values()) {
selectedObj = obj;
break;
}
答案 9 :(得分:0)
我编写了一个实用程序来从地图,条目集或迭代器中检索随机条目,键或值。
由于您不能也不应该能够计算出迭代器(Guava can do this)的大小,您必须重载randEntry()
方法以接受应该是条目长度的大小
package util;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MapUtils {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>() {
private static final long serialVersionUID = 1L;
{
put("Foo", 1);
put("Bar", 2);
put("Baz", 3);
}
};
System.out.println(randEntryValue(map));
}
static <K, V> Entry<K, V> randEntry(Iterator<Entry<K, V>> it, int count) {
int index = (int) (Math.random() * count);
while (index > 0 && it.hasNext()) {
it.next();
index--;
}
return it.next();
}
static <K, V> Entry<K, V> randEntry(Set<Entry<K, V>> entries) {
return randEntry(entries.iterator(), entries.size());
}
static <K, V> Entry<K, V> randEntry(Map<K, V> map) {
return randEntry(map.entrySet());
}
static <K, V> K randEntryKey(Map<K, V> map) {
return randEntry(map).getKey();
}
static <K, V> V randEntryValue(Map<K, V> map) {
return randEntry(map).getValue();
}
}
答案 10 :(得分:0)
如果您对O(n)
的时间复杂度感到满意,则可以使用values()
或values().toArray()
之类的方法,但是如果您寻找常量O(1)
getRandom()
的一种操作一个很好的选择是使用自定义数据结构。可以将ArrayList
和HashMap
组合起来,以O(1)
,insert()
和remove()
的时间获得getRandom()
的时间。这是一个示例实现:
class RandomizedSet {
List<Integer> nums = new ArrayList<>();
Map<Integer, Integer> valToIdx = new HashMap<>();
Random rand = new Random();
public RandomizedSet() { }
/**
* Inserts a value to the set. Returns true if the set did not already contain
* the specified element.
*/
public boolean insert(int val) {
if (!valToIdx.containsKey(val)) {
valToIdx.put(val, nums.size());
nums.add(val);
return true;
}
return false;
}
/**
* Removes a value from the set. Returns true if the set contained the specified
* element.
*/
public boolean remove(int val) {
if (valToIdx.containsKey(val)) {
int idx = valToIdx.get(val);
int lastVal = nums.get(nums.size() - 1);
nums.set(idx, lastVal);
valToIdx.put(lastVal, idx);
nums.remove(nums.size() - 1);
valToIdx.remove(val);
return true;
}
return false;
}
/** Get a random element from the set. */
public int getRandom() {
return nums.get(rand.nextInt(nums.size()));
}
}
这个想法来自this的leetcode.com问题。
答案 11 :(得分:0)
如果您使用的是Java 8,则可以在一个不错的解决方案中使用findAny
函数:
MyEntityClass myRandomlyPickedObject = myHashMap.values().stream().findAny();
答案 12 :(得分:-1)
这取决于你的密钥是什么 - hashmap的性质不允许这很容易发生。
我能想到的最好的方法是选择一个介于1和hashmap大小之间的随机数,然后开始迭代它,保持计数 - 当count等于您选择的随机数,即随机数。
答案 13 :(得分:-1)
这是一本来自Objects First with Java的练习。它如下所示.pickDefaultResponse()使用ArrayList生成一个响应并获取一个随机生成的整数并将其用作ArrayList的索引。这但是我想要克服的是填写两个列表。这里HashMap实例responseMap以及ArrayList实例defaultResponses都必须单独填写。
import java.util.HashMap;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
/**
* The responder class represents a response generator object.
* It is used to generate an automatic response, based on specified input.
* Input is presented to the responder as a set of words, and based on those
* words the responder will generate a String that represents the response.
*
* Internally, the reponder uses a HashMap to associate words with response
* strings and a list of default responses. If any of the input words is found
* in the HashMap, the corresponding response is returned. If none of the input
* words is recognized, one of the default responses is randomly chosen.
*
* @version 1.0
* @author Michael Kolling and David J. Barnes
*/
public class Responder
{
// Used to map key words to responses.
private HashMap<String, String> responseMap;
// Default responses to use if we don't recognise a word.
private ArrayList<String> defaultResponses;
private Random randomGenerator;
/**
* Construct a Responder
*/
public Responder()
{
responseMap = new HashMap<String, String>();
defaultResponses = new ArrayList<String>();
fillResponseMap();
fillDefaultResponses();
randomGenerator = new Random();
}
/**
* Generate a response from a given set of input words.
*
* @param words A set of words entered by the user
* @return A string that should be displayed as the response
*/
public String generateResponse(HashSet<String> words)
{
Iterator<String> it = words.iterator();
while(it.hasNext()) {
String word = it.next();
String response = responseMap.get(word);
if(response != null) {
return response;
}
}
// If we get here, none of the words from the input line was recognized.
// In this case we pick one of our default responses (what we say when
// we cannot think of anything else to say...)
return **pickDefaultResponse();**
}
/**
* Enter all the known keywords and their associated responses
* into our response map.
*/
private void fillResponseMap()
{
responseMap.put("crash",
"Well, it never crashes on our system. It must have something\n" +
"to do with your system. Tell me more about your configuration.");
responseMap.put("crashes",
"Well, it never crashes on our system. It must have something\n" +
"to do with your system. Tell me more about your configuration.");
responseMap.put("slow",
"I think this has to do with your hardware. Upgrading your processor\n" +
"should solve all performance problems. Have you got a problem with\n" +
"our software?");
responseMap.put("performance",
"Performance was quite adequate in all our tests. Are you running\n" +
"any other processes in the background?");
responseMap.put("bug",
"Well, you know, all software has some bugs. But our software engineers\n" +
"are working very hard to fix them. Can you describe the problem a bit\n" +
"further?");
responseMap.put("buggy",
"Well, you know, all software has some bugs. But our software engineers\n" +
"are working very hard to fix them. Can you describe the problem a bit\n" +
"further?");
responseMap.put("windows",
"This is a known bug to do with the Windows operating system. Please\n" +
"report it to Microsoft. There is nothing we can do about this.");
responseMap.put("macintosh",
"This is a known bug to do with the Mac operating system. Please\n" +
"report it to Apple. There is nothing we can do about this.");
responseMap.put("expensive",
"The cost of our product is quite competitive. Have you looked around\n" +
"and really compared our features?");
responseMap.put("installation",
"The installation is really quite straight forward. We have tons of\n" +
"wizards that do all the work for you. Have you read the installation\n" +
"instructions?");
responseMap.put("memory",
"If you read the system requirements carefully, you will see that the\n" +
"specified memory requirements are 1.5 giga byte. You really should\n" +
"upgrade your memory. Anything else you want to know?");
responseMap.put("linux",
"We take Linux support very seriously. But there are some problems.\n" +
"Most have to do with incompatible glibc versions. Can you be a bit\n" +
"more precise?");
responseMap.put("bluej",
"Ahhh, BlueJ, yes. We tried to buy out those guys long ago, but\n" +
"they simply won't sell... Stubborn people they are. Nothing we can\n" +
"do about it, I'm afraid.");
}
/**
* Build up a list of default responses from which we can pick one
* if we don't know what else to say.
*/
private void fillDefaultResponses()
{
defaultResponses.add("That sounds odd. Could you describe that problem in more detail?");
defaultResponses.add("No other customer has ever complained about this before. \n" +
"What is your system configuration?");
defaultResponses.add("That sounds interesting. Tell me more...");
defaultResponses.add("I need a bit more information on that.");
defaultResponses.add("Have you checked that you do not have a dll conflict?");
defaultResponses.add("That is explained in the manual. Have you read the manual?");
defaultResponses.add("Your description is a bit wishy-washy. Have you got an expert\n" +
"there with you who could describe this more precisely?");
defaultResponses.add("That's not a bug, it's a feature!");
defaultResponses.add("Could you elaborate on that?");
}
/**
* Randomly select and return one of the default responses.
* @return A random default response
*/
private String **pickDefaultResponse()**
{
// Pick a random number for the index in the default response list.
// The number will be between 0 (inclusive) and the size of the list (exclusive).
int index = randomGenerator.nextInt(defaultResponses.size());
return defaultResponses.get(index);
}
}