Is there a way to get the value of a HashMap rando

2020-01-27 03:19发布

Is there a way to get the value of a HashMap randomly in Java?

11条回答
Deceive 欺骗
2楼-- · 2020-01-27 04:10

Usually you do not really want a random value but rather just any value, and then it's nice doing this:

Object selectedObj = null;
for (Object obj : map.values()) {
    selectedObj = obj;
    break;
}
查看更多
ゆ 、 Hurt°
3楼-- · 2020-01-27 04:14

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();
    }
查看更多
手持菜刀,她持情操
4楼-- · 2020-01-27 04:15

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.

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.

 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.

查看更多
Fickle 薄情
5楼-- · 2020-01-27 04:16

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 keys from a given map, without the map changing in between getting the random keys, then use the random sampling method as 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 key for 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/list of the keys from which you select a random key.
查看更多
时光不老,我们不散
6楼-- · 2020-01-27 04:16

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...

  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;
      }

  }
查看更多
登录 后发表回答