¿Es posible para nosotros implementar un HashMap con una clave y dos valores? Justo como HashMap?
Por favor, ayúdenme, también diciendo (si no hay forma) alguna otra forma de implementar el almacenamiento de tres valores con uno como clave.
¿Es posible para nosotros implementar un HashMap con una clave y dos valores? Justo como HashMap?
Por favor, ayúdenme, también diciendo (si no hay forma) alguna otra forma de implementar el almacenamiento de tres valores con uno como clave.
Respuestas:
Tú podrías:
Map<KeyType, List<ValueType>>.Map<KeyType, WrapperType>.Map<KeyType, Tuple<Value1Type, Value2Type>>.1. Mapa con la lista como valor
// create our map
Map<String, List<Person>> peopleByForename = new HashMap<>();
// populate it
List<Person> people = new ArrayList<>();
people.add(new Person("Bob Smith"));
people.add(new Person("Bob Jones"));
peopleByForename.put("Bob", people);
// read from it
List<Person> bobs = peopleByForename["Bob"];
Person bob1 = bobs[0];
Person bob2 = bobs[1];
La desventaja de este enfoque es que la lista no está vinculada exactamente a dos valores.
2. Usando la clase wrapper
// define our wrapper
class Wrapper {
public Wrapper(Person person1, Person person2) {
this.person1 = person1;
this.person2 = person2;
}
public Person getPerson1 { return this.person1; }
public Person getPerson2 { return this.person2; }
private Person person1;
private Person person2;
}
// create our map
Map<String, Wrapper> peopleByForename = new HashMap<>();
// populate it
Wrapper people = new Wrapper();
peopleByForename.put("Bob", new Wrapper(new Person("Bob Smith"),
new Person("Bob Jones"));
// read from it
Wrapper bobs = peopleByForename.get("Bob");
Person bob1 = bobs.getPerson1;
Person bob2 = bobs.getPerson2;
La desventaja de este enfoque es que debe escribir mucho código de placa de caldera para todas estas clases de contenedores muy simples.
3. Usando una tupla
// you'll have to write or download a Tuple class in Java, (.NET ships with one)
// create our map
Map<String, Tuple2<Person, Person> peopleByForename = new HashMap<>();
// populate it
peopleByForename.put("Bob", new Tuple2(new Person("Bob Smith",
new Person("Bob Jones"));
// read from it
Tuple<Person, Person> bobs = peopleByForename["Bob"];
Person bob1 = bobs.Item1;
Person bob2 = bobs.Item2;
Esta es la mejor solución en mi opinión.
4. Múltiples mapas
// create our maps
Map<String, Person> firstPersonByForename = new HashMap<>();
Map<String, Person> secondPersonByForename = new HashMap<>();
// populate them
firstPersonByForename.put("Bob", new Person("Bob Smith"));
secondPersonByForename.put("Bob", new Person("Bob Jones"));
// read from them
Person bob1 = firstPersonByForename["Bob"];
Person bob2 = secondPersonByForename["Bob"];
La desventaja de esta solución es que no es obvio que los dos mapas estén relacionados, un error programático podría hacer que los dos mapas no estén sincronizados.
Map<KeyType, Tuple<Value1Type, Value2Type>>
No, no solo como un HashMap. Básicamente, necesitaría una HashMapclave a una colección de valores.
Si está contento de usar bibliotecas externas, Guava tiene exactamente este concepto Multimapcon implementaciones como ArrayListMultimapy HashMultimap.
ArrayListMultimaptú ... o simplemente usarías una HashMap<String, List<Integer>>o lo que sea. Tendría que crear una lista vacía cada vez que se agrega un valor por primera vez, básicamente.
HashMap<String, List<Integer>>
Otra buena opción es usar MultiValuedMap de Apache Commons. Eche un vistazo a Todas las clases de implementación conocidas en la parte superior de la página para implementaciones especializadas.
Ejemplo:
HashMap<K, ArrayList<String>> map = new HashMap<K, ArrayList<String>>()
podría ser reemplazado con
MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>();
Entonces,
map.put(key, "A");
map.put(key, "B");
map.put(key, "C");
Collection<String> coll = map.get(key);
daría como resultado una colección que collcontiene "A", "B" y "C".
Eche un vistazo a Multimaplas bibliotecas de guayaba y su implementación:HashMultimap
Una colección similar a un Mapa, pero que puede asociar múltiples valores con una sola clave. Si llama a put (K, V) dos veces, con la misma clave pero con valores diferentes, el mapa múltiple contiene asignaciones de la clave a ambos valores.
Lo uso Map<KeyType, Object[]>para asociar múltiples valores con una clave en un mapa. De esta manera, puedo almacenar múltiples valores de diferentes tipos asociados con una clave. Debe tener cuidado manteniendo el orden adecuado de inserción y recuperación desde el Objeto [].
Ejemplo: considere, queremos almacenar información del estudiante. La clave es id, mientras que nos gustaría almacenar el nombre, la dirección y el correo electrónico asociados al estudiante.
//To make entry into Map
Map<Integer, String[]> studenMap = new HashMap<Integer, String[]>();
String[] studentInformationArray = new String[]{"name", "address", "email"};
int studenId = 1;
studenMap.put(studenId, studentInformationArray);
//To retrieve values from Map
String name = studenMap.get(studenId)[1];
String address = studenMap.get(studenId)[2];
String email = studenMap.get(studenId)[3];
HashMap<Integer,ArrayList<String>> map = new HashMap<Integer,ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
list.add("abc");
list.add("xyz");
map.put(100,list);
Solo para el registro, la solución JDK8 pura sería utilizar el Map::computemétodo:
map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value);
Como
public static void main(String[] args) {
Map<String, List<String>> map = new HashMap<>();
put(map, "first", "hello");
put(map, "first", "foo");
put(map, "bar", "foo");
put(map, "first", "hello");
map.forEach((s, strings) -> {
System.out.print(s + ": ");
System.out.println(strings.stream().collect(Collectors.joining(", ")));
});
}
private static <KEY, VALUE> void put(Map<KEY, List<VALUE>> map, KEY key, VALUE value) {
map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value);
}
con salida:
bar: foo
first: hello, foo, hello
Tenga en cuenta que para garantizar la coherencia en caso de múltiples subprocesos tienen acceso a esta estructura de datos, ConcurrentHashMapy CopyOnWriteArrayList, por ejemplo, necesidad de ser utilizado.
computeIfAbsent. map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
Si usa Spring Framework . No es: org.springframework.util.MultiValueMap.
Para crear un mapa de valores múltiples no modificable:
Map<String,List<String>> map = ...
MultiValueMap<String, String> multiValueMap = CollectionUtils.toMultiValueMap(map);
O usar org.springframework.util.LinkedMultiValueMap
Sí, esto se llama frecuentemente a multimap.
La forma más fácil sería usar una biblioteca de colección de Google:
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
public class Test {
public static void main(final String[] args) {
// multimap can handle one key with a list of values
final Multimap<String, String> cars = ArrayListMultimap.create();
cars.put("Nissan", "Qashqai");
cars.put("Nissan", "Juke");
cars.put("Bmw", "M3");
cars.put("Bmw", "330E");
cars.put("Bmw", "X6");
cars.put("Bmw", "X5");
cars.get("Bmw").forEach(System.out::println);
// It will print the:
// M3
// 330E
// X6
// X5
}
}
Enlace Maven: https://mvnrepository.com/artifact/com.google.collections/google-collections/1.0-rc2
más sobre esto: http://tomjefferys.blogspot.be/2011/09/multimaps-google-guava.html
String key= "services_servicename"
ArrayList<String> data;
for(int i = 0; i lessthen data.size(); i++) {
HashMap<String, String> servicesNameHashmap = new HashMap<String, String>();
servicesNameHashmap.put(key,data.get(i).getServiceName());
mServiceNameArray.add(i,servicesNameHashmap);
}
Tengo los mejores resultados.
Solo tienes que crear nuevos me HashMapgusta
HashMap<String, String> servicesNameHashmap = new HashMap<String, String>();
en tu forbucle Tendrá el mismo efecto que la misma clave y múltiples valores.
import java.io.*;
import java.util.*;
import com.google.common.collect.*;
class finTech{
public static void main(String args[]){
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("1","11");
multimap.put("1","14");
multimap.put("1","12");
multimap.put("1","13");
multimap.put("11","111");
multimap.put("12","121");
System.out.println(multimap);
System.out.println(multimap.get("11"));
}
}
Salida:
{"1"=["11","12","13","14"],"11"=["111"],"12"=["121"]}
["111"]
Esta es la biblioteca Google-Guava para funcionalidades de utilidad. Esta es la solución requerida.
No pude publicar una respuesta al comentario de Paul, así que estoy creando un nuevo comentario para Vidhya aquí:
Wrapper será un SuperClasspara las dos clases que queremos almacenar como valor.
y dentro de la clase wrapper, podemos poner las asociaciones como objetos de variable de instancia para los dos objetos de clase.
p.ej
class MyWrapper {
Class1 class1obj = new Class1();
Class2 class2obj = new Class2();
...
}
y en HashMap podemos poner de esta manera,
Map<KeyObject, WrapperObject>
WrapperObj tendrá variables de clase:class1Obj, class2Obj
Puedes hacerlo implícitamente.
// Create the map. There is no restriction to the size that the array String can have
HashMap<Integer, String[]> map = new HashMap<Integer, String[]>();
//initialize a key chosing the array of String you want for your values
map.put(1, new String[] { "name1", "name2" });
//edit value of a key
map.get(1)[0] = "othername";
Esto es muy simple y efectivo. Si desea valores de diferentes clases, puede hacer lo siguiente:
HashMap<Integer, Object[]> map = new HashMap<Integer, Object[]>();
Se puede hacer usando un identityHashMap, sujeto a la condición de que la comparación de claves será realizada por == operador y no es igual a ().
Estoy tan acostumbrado a hacer esto con un Diccionario de datos en el Objetivo C. Fue más difícil obtener un resultado similar en Java para Android. Terminé creando una clase personalizada y luego haciendo un hashmap de mi clase personalizada.
public class Test1 {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addview);
//create the datastring
HashMap<Integer, myClass> hm = new HashMap<Integer, myClass>();
hm.put(1, new myClass("Car", "Small", 3000));
hm.put(2, new myClass("Truck", "Large", 4000));
hm.put(3, new myClass("Motorcycle", "Small", 1000));
//pull the datastring back for a specific item.
//also can edit the data using the set methods. this just shows getting it for display.
myClass test1 = hm.get(1);
String testitem = test1.getItem();
int testprice = test1.getPrice();
Log.i("Class Info Example",testitem+Integer.toString(testprice));
}
}
//custom class. You could make it public to use on several activities, or just include in the activity if using only here
class myClass{
private String item;
private String type;
private int price;
public myClass(String itm, String ty, int pr){
this.item = itm;
this.price = pr;
this.type = ty;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getType() {
return item;
}
public void setType(String type) {
this.type = type;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
Podemos crear una clase para tener múltiples claves o valores y el objeto de esta clase se puede usar como parámetro en el mapa. Puede consultar https://stackoverflow.com/a/44181931/8065321
Uso de recopiladores de Java
// Group employees by department
Map<Department, List<Employee>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
donde departamento es tu llave
Pruebe LinkedHashMap , muestra:
Map<String,String> map = new LinkedHashMap<String,String>();
map.put('1','linked');map.put('1','hash');
map.put('2','map');map.put('3','java');..
salida:
claves: 1,1,2,3
valores: vinculado, hash, mapa, java
linkedya no existirá en el mapa porque lo reemplazaste por hash.