Czy istnieje sposób na losowe uzyskanie wartości Hashmapy w Javie?

Czy istnieje sposób na losowe uzyskanie wartości Hashmapy w Javie?

Author: Varuna, 2009-05-30

12 answers

Przydałoby się coś w stylu:

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

Aktualizacja.

Powyższe nie działa, Set.toArray() zawsze zwraca tablicę Object s, której nie można przymusić do tablicy Map.Entry.

Ta (prostsza wersja) działa:

Random generator = new Random();
Object[] values = myHashMap.values().toArray();
Object randomValue = values[generator.nextInt(values.length)];

Jeśli chcesz, aby losowa wartość była typem innym niż Object, po prostu dodaj rzut do ostatniej linii. Więc jeśli myHashMap zostało zadeklarowane jako:

Map<Integer,String> myHashMap = new HashMap<Integer,String>();

Ostatnia linijka może być:

String randomValue = (String) values[generator.nextInt(value.length)];
 43
Author: Tom Jefferys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-07 13:20:23

Ponieważ wymagania wymagają tylko losowej wartości z HashMap, Oto podejście:

  1. The HashMap ma values metoda zwracająca Collection wartości na mapie.
  2. {[4] } jest używany do tworzenia List.
  3. The size metoda służy do znalezienia rozmiaru List, który jest używany przez Random.nextInt metoda uzyskania losowego indeksu List.
  4. wreszcie, wartość jest pobierana z List get metoda z indeksem losowym.

Realizacja:

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

Miłą częścią tego podejścia jest to, że wszystkie metody są ogólne - nie ma potrzeby pisania.

 28
Author: coobird,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-30 13:09:55

Jeśli musisz narysować dalsze wartości z mapy bez powtarzania żadnych elementów, możesz umieścić mapę na liście, a następnie przetasować ją.

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

for ( Object obj : valuesList ) {
    System.out.println( obj );
}
 9
Author: banjollity,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-30 12:29:02

Wygeneruj losową liczbę od 0 do liczby kluczy w twoim HashMap. Zdobądź klucz przy losowej liczbie. Uzyskaj wartość z tego klucza.

Pseudocode:

 int n =  random(map.keys().length());
 String key = map.keys().at(n);
 Object value = map.at(key);

Jeśli jest to trudne do zaimplementowania w Javie, możesz utworzyć z tego kodu tablicę używając funkcji toArray() w Set.

 Object[] values = map.values().toArray(new Object[map.size()]);
 Object random_value = values[random(values.length)];
Nie jestem pewien, jak zrobić losową liczbę.
 3
Author: Peter Stuifzand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-30 11:23:08

Dobra odpowiedź zależy nieco od okoliczności, w szczególności od tego, jak często trzeba uzyskać losowy klucz dla danej mapy (N. B. technika jest zasadniczo taka sama, czy wziąć klucz lub wartość).

  • Jeśli potrzebujesz różnych losowych klawiszy z danej mapy, bez mapy zmiana pomiędzy otrzymaniem losowych klawiszy, następnie użyj losowe metoda pobierania próbek as you iterate przez zestaw kluczy. Skutecznie co robisz to jest iterate nad set zwracane przez keySet (), a na każdym item Oblicz prawdopodobieństwo chcąc wziąć ten klucz, biorąc pod uwagę, jak wiele trzeba będzie ogólnie i numer, który zająłeś do tej pory. Wtedy Wygeneruj losową liczbę i sprawdź, czy liczba ta jest niższa niż prawdopodobieństwo. (N. B. ta metoda zawsze będzie działać , nawet jeśli potrzebujesz tylko 1 klucza; po prostu niekoniecznie jest to najbardziej efektywny sposób w tym przypadku.)
  • klucze w Hashmapie są skutecznie już w pseudolosowej kolejności. W extreme case where you will only ever need one random key for a biorąc pod uwagę możliwą mapę, można nawet po prostu wyciągnij pierwszy element keySet () .
  • W innych przypadkach (Gdzie albo potrzeba wielu możliwych losowych klawiszy dla danej możliwej mapy lub mapy zmieni się między Tobą biorąc losowo klucze), w zasadzie trzeba Tworzenie lub utrzymywanie tablicy / listy kluczy, z których wybieramy losowy klucz.
 1
Author: Neil Coffey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-30 17:03:09

Naprawdę Nie wiem, dlaczego chcesz to zrobić... ale jeśli to pomoże, stworzyłem Randommapę, która automatycznie losuje wartości podczas wywoływania values (), wtedy następująca uruchomiona aplikacja demonstracyjna może wykonać zadanie...

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

  }
 0
Author: kctang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-30 12:14:26

Oto przykład użycia metody tablic opisanej przez Petera Stuifzanda, również za pomocą metody 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) );
 0
Author: MH114,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-30 12:30:02

Zazwyczaj tak naprawdę nie chcesz losowej wartości, ale raczej dowolnej wartości, a potem miło jest to robić:

Object selectedObj = null;
for (Object obj : map.values()) {
    selectedObj = obj;
    break;
}
 0
Author: Kalisky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-07 12:07:20

Konwersja go do tablicy, a następnie uzyskanie wartości jest zbyt wolne, gdy jest w gorącej ścieżce.

Więc pobierz zestaw (albo klucz lub zestaw keyvalue) i zrób coś w stylu:

    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();
    }
 0
Author: Quonux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-29 19:30:07

Napisałem narzędzie do pobierania losowego wpisu, klucza lub wartości z mapy, zestawu wpisów lub iteratora.

Ponieważ nie możesz i nie powinieneś być w stanie określić rozmiaru iteratora (Guava może to zrobić), będziesz musiał przeciążyć metodę randEntry(), aby zaakceptować rozmiar, który powinien być długością wpisów.

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();
    }
}
 0
Author: Mr. Polywhirl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-23 19:19:56

To zależy od tego, jaki jest Twój klucz - natura hashmapy nie pozwala na to łatwo.

Sposób, w jaki mogę myśleć o czubku mojej głowy, to wybranie losowej liczby między 1 A rozmiarem hashmapy, a następnie rozpoczęcie iteracji nad nią, zachowując licznik na bieżąco - gdy licznik jest równy tej losowej liczbie, którą wybrałeś, to jest Twój losowy element.

 -1
Author: Kazar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-30 11:10:41

Jest to ćwiczenie z książki Obiekty najpierw z Java.It jest jak poniżej.Metoda pickDefaultResponse () generuje odpowiedź za pomocą ArrayList i otrzymuje losowo wygenerowaną liczbę całkowitą i używa jej jako indeksu ArrayList.to działa, ale to, co chciałem przezwyciężyć, to wypełnienie dwóch List.Tutaj Responsemap wystąpienia HashMap, jak również ArrayList wystąpienia defaultResponses oba muszą być wypełnione oddzielnie.

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);
    }
}
 -1
Author: Varuna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-30 14:02:42