example ejemplo java collections hashmap

ejemplo - hashmap java example



¿Hay una manera de obtener el valor de un HashMap al azar en Java? (12)

Aquí hay un ejemplo de cómo usar el enfoque de arrays descrito por Peter Stuifzand, también a través del método de 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) );

¿Hay una manera de obtener el valor de un HashMap al azar en Java?


Convertirlo en una matriz y luego obtener el valor es demasiado lento cuando está en la ruta activa.

así que obtenga el conjunto (ya sea la clave o el conjunto de valores de clave) y haga algo como:

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


Dado que los requisitos solo piden un valor aleatorio de HashMap , aquí está el enfoque:

  1. El HashMap tiene un método de values que devuelve una Collection de los valores en el mapa.
  2. La Collection se utiliza para crear una List .
  3. El método de size se usa para encontrar el tamaño de la List , que es usado por el método Random.nextInt para obtener un índice aleatorio de la List .
  4. Finalmente, el valor se recupera del método List get con el índice aleatorio.

Implementación:

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

Lo bueno de este enfoque es que todos los métodos son generic , no hay necesidad de encasillamiento.


Depende de cuál sea tu clave: la naturaleza de un hashmap no permite que esto suceda fácilmente.

La forma en que puedo pensar fuera de la cabeza es seleccionar un número aleatorio entre 1 y el tamaño del hashmap, y luego comenzar a iterar sobre él, manteniendo un conteo a medida que avanza, cuando el conteo es igual a ese número aleatorio que Elige, ese es tu elemento aleatorio.


Escribí una utilidad para recuperar una entrada, clave o valor aleatorio de un mapa, conjunto de entradas o iterador.

Como no puede y no debe poder calcular el tamaño de un iterador ( Guava puede hacer esto ), tendrá que sobrecargar el método randEntry() para aceptar un tamaño que debería ser la longitud de las entradas.

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


Este es un ejercicio del libro Objetos primero con Java. Es el siguiente. El pickDefaultResponse () genera una respuesta usando un ArrayList y obteniendo un entero generado aleatoriamente y usándolo como el índice del ArrayList. Esto funciona. Pero lo que quería superar era llenar dos Listas. Aquí, el mapa de respuesta de la instancia de HashMap, así como la respuesta predeterminada de la ArrayList, ambas tienen que llenarse por separado.

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


Genere un número aleatorio entre 0 y la cantidad de claves en su HashMap . Obtener la clave en el número aleatorio. Obtener el valor de esa clave.

Pseudocódigo

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

Si es difícil de implementar esto en Java, entonces puede crear y crear una matriz a partir de este código usando la función toArray() en Set .

Object[] values = map.values().toArray(new Object[map.size()]); Object random_value = values[random(values.length)];

No estoy realmente seguro de cómo hacer el número aleatorio.


Podrías usar algo como:

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

Actualizar.

Lo anterior no funciona , Set.toArray() siempre devuelve una matriz de Object , que no puede ser forzada en una matriz de Map.Entry .

Esta (versión más simple) funciona:

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

Si desea que el valor aleatorio sea un tipo que no sea un Object simplemente agregue una conversión a la última línea. Entonces si myHashMap fue declarado como:

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

La última línea puede ser:

String randomValue = (String) values[generator.nextInt(value.length)];


Por lo general, realmente no desea un valor aleatorio , sino cualquier valor, y es bueno hacer esto:

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


Realmente no sé por qué quieres hacer esto ... pero si ayuda, he creado un RandomMap que automáticamente asigna valores aleatorios cuando llamas a valores (), entonces la siguiente aplicación de demostración ejecutable puede hacer el trabajo ... .

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


Si necesita dibujar otros valores del mapa sin repetir ningún elemento, puede poner el mapa en una Lista y luego barajarlo.

List<Object> valuesList = new ArrayList<Object>(map.values()); Collections.shuffle( valuesList ); for ( Object obj : valuesList ) { System.out.println( obj ); }


Una buena respuesta depende ligeramente de las circunstancias, en particular con qué frecuencia necesita obtener una clave aleatoria para un mapa dado (NB: la técnica es esencialmente la misma, ya sea que tome la clave o el valor).

  • Si necesita varias claves aleatorias de un mapa determinado, sin que el mapa cambie entre las claves aleatorias, utilice el método de muestreo aleatorio a medida que recorre el conjunto de claves. Efectivamente, lo que haces es iterar sobre el conjunto devuelto por keySet (), y en cada elemento calcula la probabilidad de querer tomar esa clave, dado el número total que necesitarás y el número que has tomado hasta ahora. Luego genere un número aleatorio y vea si ese número es más bajo que la probabilidad. (Nota: este método siempre funcionará , incluso si solo necesita una tecla; en este caso, no es necesariamente la forma más eficiente).
  • Las claves en un HashMap ya están efectivamente en orden pseudoaleatorio. En un caso extremo en el que solo necesitará una clave aleatoria para un mapa posible, incluso podría extraer el primer elemento del conjunto de teclas () .
  • En otros casos (cuando necesite varias claves aleatorias posibles para un mapa posible dado, o el mapa cambiará entre usted tomando claves aleatorias), esencialmente tiene que crear o mantener una matriz / lista de las claves de las que selecciona un azar llave.