HashMap com vários valores sob a mesma chave

É possível implementarmos um HashMap com uma chave e dois valores. Apenas como HashMap?

Por favor, me ajude, também dizendo (se não houver) alguma outra maneira de implementar o armazenamento de três valores com um como chave?

Você poderia:

  1. Use um mapa que tenha uma lista como o valor. Map> .
  2. Crie uma nova class de wrapper e coloque instâncias desse wrapper no mapa. Map .
  3. Use uma class como tupla (salva a criação de lotes de wrappers). Map> .
  4. Use vários mapas lado a lado.

Exemplos

1. Mapeie com lista como o valor

 // create our map Map> peopleByForename = new HashMap>(); // populate it List people = new ArrayList(); people.add(new Person("Bob Smith")); people.add(new Person("Bob Jones")); peopleByForename.put("Bob", people); // read from it List bobs = peopleByForename["Bob"]; Person bob1 = bobs[0]; Person bob2 = bobs[1]; 

A desvantagem dessa abordagem é que a lista não está vinculada a exatamente dois valores.

2. Usando class 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 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["Bob"]; Person bob1 = bobs.Person1; Person bob2 = bobs.Person2; 

A desvantagem dessa abordagem é que você tem que escrever um monte de código de placa de caldeira para todas essas classs de contêineres muito simples.

3. Usando uma tupla

 // you'll have to write or download a Tuple class in Java, (.NET ships with one) // create our map Map peopleByForename = new HashMap>(); // populate it peopleByForename.put("Bob", new Tuple2(new Person("Bob Smith", new Person("Bob Jones")); // read from it Tuple bobs = peopleByForename["Bob"]; Person bob1 = bobs.Item1; Person bob2 = bobs.Item2; 

Esta é a melhor solução na minha opinião.

4. Vários mapas

 // create our maps Map firstPersonByForename = new HashMap(); Map 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"]; 

A desvantagem dessa solução é que não é óbvio que os dois mapas estejam relacionados, um erro programático poderia fazer com que os dois mapas fiquem fora de sincronia.

Não, não apenas como um HashMap . Você basicamente precisaria de um HashMap de uma chave para uma coleção de valores.

Se você gosta de usar bibliotecas externas, o Guava possui exatamente esse conceito no Multimap com implementações como ArrayListMultimap e HashMultimap .

Outra boa opção é usar o MultiValuedMap do Apache Commons. Dê uma olhada nas Classes de Implementação Todas as Conhecidas no topo da página para implementações especializadas.

Exemplo:

 HashMap> map = new HashMap>() 

poderia ser substituído por

 MultiValuedMap map = new MultiValuedHashMap(); 

Assim,

 map.put(key, "A"); map.put(key, "B"); map.put(key, "C"); Collection coll = map.get(key); 

resultaria em coll coleção contendo “A”, “B” e “C”.

Dê uma olhada no Multimap partir das bibliotecas de goiabeiras e sua implementação – HashMultimap

Uma coleção semelhante a um mapa, mas que pode associar vários valores a uma única chave. Se você chamar put (K, V) duas vezes, com a mesma chave, mas valores diferentes, o multimap contém mapeamentos da chave para ambos os valores.

Eu uso Map para associar vários valores a uma chave em um mapa. Dessa forma, posso armazenar vários valores de diferentes tipos associados a uma chave. Você deve tomar cuidado mantendo a ordem correta de inserção e recuperação de Object [].

Exemplo: considere, queremos armazenar informações do aluno. Key é id, enquanto gostaríamos de armazenar o nome, endereço e e-mail associados ao aluno.

  //To make entry into Map Map studenMap = new HashMap(); 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> map = new HashMap>(); ArrayList list = new ArrayList(); list.add("abc"); list.add("xyz"); map.put(100,list); 

Apenas para o registro, a solução JDK8 pura seria usar o método Map::compute :

 map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value); 

Tal como

 public static void main(String[] args) { Map> 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  void put(Map> map, KEY key, VALUE value) { map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value); } 

com saída:

 bar: foo first: hello, foo, hello 

Observe que, para garantir a consistência no caso de vários encadeamentos acessarem essa estrutura de dados, ConcurrentHashMap e CopyOnWriteArrayList por exemplo, precisam ser usados.

Se você usa o Spring Framework . Existe: org.springframework.util.MultiValueMap .

Para criar um mapa multi-valor não modificável:

 Map> map = ... MultiValueMap multiValueMap = CollectionUtils.toMultiValueMap(map); 

Ou use org.springframework.util.LinkedMultiValueMap

Sim e não. A solução é criar um cluster Wrapper para seus valores que contenham os 2 (3 ou mais) valores que correspondem à sua chave.

A maneira mais fácil seria usar uma biblioteca de collections do Google:

import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap;

teste de class pública {

 public static void main(final String[] args) { // multimap can handle one key with a list of values final Multimap 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 } 

}

link maven: https://mvnrepository.com/artifact/com.google.collections/google-collections/1.0-rc2

mais sobre isso: http://tomjefferys.blogspot.be/2011/09/multimaps-google-guava.html

Eu não pude postar uma resposta sobre o comentário de Paulo, então estou criando um novo comentário para Vidhya aqui:

Wrapper será um SuperClass para as duas classs que queremos armazenar como um valor.

e dentro da class wrapper, podemos colocar as associações como objects da variável de instância para os dois objects de class.

por exemplo

 class MyWrapper { Class1 class1obj = new Class1(); Class2 class2obj = new Class2(); ... } 

e no HashMap podemos colocar dessa maneira,

 Map 

WrapperObj terá variables ​​de class: class1Obj, class2Obj

Você pode fazer isso implicitamente.

 // Create the map. There is no restriction to the size that the array String can have HashMap map = new HashMap(); //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"; 

Isso é muito simples e eficaz. Se você quiser valores de classs diferentes, você pode fazer o seguinte:

 HashMap map = new HashMap(); 

Pode ser feito usando um identityHashMap, sujeito à condição de que a comparação de chaves seja feita pelo operador == e não igual a ().

Eu prefiro o seguinte para armazenar qualquer número de variables ​​sem ter que criar uma class separada.

 final public static Map> myMap = new HashMap>(); 

Aqui está a resposta:):)

String key = “services_servicename”

Dados ArrayList;

para (int i = 0; i lessthen data.size (); i ++) {

  HashMap servicesNameHashmap = new HashMap(); servicesNameHashmap.put(key,data.get(i).getServiceName()); mServiceNameArray.add(i,servicesNameHashmap); } 

Eu tenho os melhores resultados.

Você só precisa criar um novo hashmap como

Serviços HashMapNameHashmap = new HashMap ();

no seu loop. Terá o mesmo efeito como a mesma chave e vários valores.

Codificação Feliz 🙂

Estou tão acostumado a fazer isso com um Data Dictionary no Objective C. Foi mais difícil obter um resultado semelhante no Java para Android. Acabei criando uma class personalizada e fazendo um hashmap da minha class personalizada.

 public class Test1 { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.addview); //create the datastring HashMap hm = new HashMap(); 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 criar uma class para ter várias chaves ou valores e o object dessa class pode ser usado como um parâmetro no mapa. Você pode consultar https://stackoverflow.com/a/44181931/8065321

Tente LinkedHashMap , amostra:

 Map map = new LinkedHashMap(); map.put('1','linked');map.put('1','hash'); map.put('2','map');map.put('3','java');.. 

saída:

chaves: 1,1,2,3

valores: vinculado, hash, mapa, java