Подтвердить что ты не робот

Есть ли способ случайно получить значение HashMap в Java?

Есть ли способ случайно получить значение HashMap в Java?

4b9b3361

Ответ 1

Это работает:

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 s, который не может быть приведен в массив Map.Entry.

Random generator = new Random();
Map.Entry[] entries = myHashMap.entrySet().toArray();
randomValue = entries[generator.nextInt(entries.length)].getValue();

Ответ 2

Поскольку требования только запрашивают случайное значение из 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 - нет необходимости в приведении типов.

Ответ 3

Если вам нужно нарисовать дальнейшие значения с карты, не повторяя никаких элементов, вы можете поместить карту в список и затем перетасовать ее.

List<Object> valuesList = new ArrayList<Object>(map.values());
Collections.shuffle( valuesList );

for ( Object obj : valuesList ) {
    System.out.println( obj );
}

Ответ 4

Создайте случайное число между 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)];

Я не уверен, как сделать случайное число.

Ответ 5

Хороший ответ немного зависит от обстоятельств, в частности, как часто вам нужно получить случайный ключ для данной карты (N.B., метод по существу тот же, независимо от того, используете ли вы ключ или значение).

  • Если вам нужны различные случайные клавиши из заданного отображения без отображения изменение между получением случайные ключи, затем используйте random метод выборки, когда вы повторяете через набор ключей. Эффективно, что вы выполняете перебор по набору возвращенный keySet(), и на каждом item вычислить вероятность желая взять этот ключ, учитывая, как многие вам понадобятся в целом, и номер, который вы сделали до сих пор. затем генерировать случайное число и видеть, если это число меньше, чем вероятность. (N.B. Этот метод всегда будет работать, даже если вам нужен только 1 ключ, это не обязательно самый эффективный способ в этом случае.)
  • Ключи в HashMap эффективны в псевдослучайном порядке. В крайний случай, когда вы будете нужен один случайный ключ для учитывая возможную карту, вы могли бы даже просто вытащите первый элемент Keyset().
  • В других случаях (где вы либо требуется несколько возможных случайных ключей для заданной возможной карты или карты будет изменяться между вами, принимая случайные ключи), вам, по сути, нужно создать или сохранить массив/список ключей, с которых вы выбираете случайный ключ.

Ответ 6

Преобразование его в массив, а затем получение значения слишком медленно, когда оно находится в горячем пути.

чтобы получить набор (либо набор ключей или набора ключей), либо сделать что-то вроде:

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

Ответ 7

Вот пример того, как использовать метод массивов, описанный Петром Штюфзаном, также через метод 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) );

Ответ 8

Я действительно не знаю, почему вы хотите это сделать... но если это помогает, я создал RandomMap, который автоматически рандомизирует значения, когда вы вызываете значения(), тогда следующее исполняемое демо-приложение может выполнить работа...

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

  }

Ответ 9

Обычно вам не требуется значение random, а просто любое значение, и тогда это приятно делать:

Object selectedObj = null;
for (Object obj : map.values()) {
    selectedObj = obj;
    break;
}

Ответ 10

Я написал утилиту для извлечения случайной записи, ключа или значения из карты, набора записей или итератора.

Поскольку вы не можете и не можете определить размер итератора (Guava может это сделать), вам придется перегружать 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();
    }
}

Ответ 11

Это зависит от того, что ваш ключ - природа хэш-карты не позволяет это легко случиться.

То, как я могу думать о моей голове, состоит в том, чтобы выбрать случайное число между 1 и размером хэш-карты, а затем начать итерацию по нему, поддерживая счет, когда вы идете - когда счетчик равен этому случайный номер, который вы выбрали, это ваш случайный элемент.

Ответ 12

Это упражнение из книги Objects First With Java. Это как показано ниже. PickDefaultResponse() генерирует ответ с использованием ArrayList и получает произвольно генерируемое целое число и использует его как индекс ArrayList. Это работает. Но то, что я хотел преодолеть, было заполнение двух списков. Здесь необходимо, чтобы экземпляр responseMap экземпляра HashMap, а также экземпляр экземпляра ArrayList по умолчанию должны быть заполнены отдельно.

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 not a bug, it 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);
    }
}