Можем ли мы реализовать HashMap с одним ключом и двумя значениями. Так же, как HashMap?
Пожалуйста, помогите мне, также рассказав (если нет никакого способа) какой-либо другой способ реализовать хранение трех значений с одним в качестве ключа?
Недостаток этого подхода заключается в том, что для всех этих очень простых классов контейнеров вам нужно написать много кода.
3. Использование кортежа
// you'll have to write or download a Tuple class in Java, (.NET ships with one)// create our mapMap<String,Tuple2<Person,Person> peopleByForename =newHashMap<>();// populate it
peopleByForename.put("Bob",newTuple2(newPerson("Bob Smith",newPerson("Bob Jones"));// read from itTuple<Person,Person> bobs = peopleByForename["Bob"];Person bob1 = bobs.Item1;Person bob2 = bobs.Item2;
@ Jon, не могли бы вы предоставить рабочий пример на Java для вышеупомянутого вопроса, заданного OP. Высоко признателен, если вы могли бы опубликовать его
Deepak
2
@Deepak: поиск примеров мультикарты гуавы, и вы найдете пример кода.
Джон Скит
1
@Deepak: По сути, вы бы построили что-то вроде ArrayListMultimapсебя ... или просто использовали HashMap<String, List<Integer>>или что-то еще. Вам нужно будет создать пустой список каждый раз, когда значение добавляется в первый раз, в основном.
Джон Скит
1
у вас есть рабочий пример дляHashMap<String, List<Integer>>
Дипак
9
@Deepak: Я предлагаю вам попробовать создать пример самостоятельно, и если вы застряли, задайте вопрос, включая код, насколько это у вас есть. Вы узнаете намного больше таким образом.
Джон Скит
23
Другим хорошим выбором является использование MultiValuedMap от Apache Commons. Взгляните на Все известные классы реализации в верхней части страницы для специализированных реализаций.
Взгляните на Multimapguava-библиотеки и их реализацию -HashMultimap
Коллекция, похожая на карту, но которая может связывать несколько значений с одним ключом. Если вы вызываете put (K, V) дважды, с одним и тем же ключом, но разными значениями, мультикарта содержит сопоставления ключа с обоими значениями.
Я использую Map<KeyType, Object[]>для связывания нескольких значений с ключом в карте. Таким образом, я могу хранить несколько значений разных типов, связанных с ключом. Вы должны позаботиться о поддержании правильного порядка вставки и извлечения из Object [].
Пример. Предположим, мы хотим хранить информацию об ученике. Ключ - это идентификатор, в то время как мы хотели бы сохранить имя, адрес и адрес электронной почты, связанные со студентом.
//To make entry into MapMap<Integer,String[]> studenMap =newHashMap<Integer,String[]>();String[] studentInformationArray =newString[]{"name","address","email"};int studenId =1;
studenMap.put(studenId, studentInformationArray);//To retrieve values from MapString name = studenMap.get(studenId)[1];String address = studenMap.get(studenId)[2];String email = studenMap.get(studenId)[3];
Обратите внимание, что для обеспечения согласованности в случае, если несколько потоков обращаются к этой структуре данных, ConcurrentHashMapи, CopyOnWriteArrayListнапример, необходимо использовать.
Да и нет. Решение состоит в том, чтобы создать классы Wrapper для ваших значений, которые содержат 2 (3 или более) значения, которые соответствуют вашему ключу.
Самый простой способ - использовать библиотеку коллекции Google:
import com.google.common.collect.ArrayListMultimap;import com.google.common.collect.Multimap;publicclassTest{publicstaticvoid main(finalString[] args){// multimap can handle one key with a list of valuesfinalMultimap<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}}
// Create the map. There is no restriction to the size that the array String can haveHashMap<Integer,String[]> map =newHashMap<Integer,String[]>();//initialize a key chosing the array of String you want for your values
map.put(1,newString[]{"name1","name2"});//edit value of a key
map.get(1)[0]="othername";
Это очень просто и эффективно. Если вы хотите использовать значения разных классов, вы можете сделать следующее:
Я так привык просто делать это с помощью словаря данных в Objective C. Было сложнее получить подобный результат в Java для Android. В итоге я создал собственный класс, а затем просто создал хэш-карту своего пользовательского класса.
publicclassTest1{@Overrideprotectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.addview);//create the datastringHashMap<Integer, myClass> hm =newHashMap<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 hereclass myClass{privateString item;privateString type;privateint price;public myClass(String itm,String ty,int pr){this.item = itm;this.price = pr;this.type = ty;}publicString getItem(){return item;}publicvoid setItem(String item){this.item = item;}publicString getType(){return item;}publicvoid setType(String type){this.type = type;}publicint getPrice(){return price;}publicvoid setPrice(int price){this.price = price;}}
Мы можем создать класс, имеющий несколько ключей или значений, и объект этого класса можно использовать в качестве параметра на карте. Вы можете обратиться к https://stackoverflow.com/a/44181931/8065321
Ответы:
Ты мог:
Map<KeyType, List<ValueType>>
,Map<KeyType, WrapperType>
,Map<KeyType, Tuple<Value1Type, Value2Type>>
,Примеры
1. Карта со списком в качестве значения
Недостаток этого подхода заключается в том, что список не привязан к точно двум значениям.
2. Использование класса-обертки
Недостаток этого подхода заключается в том, что для всех этих очень простых классов контейнеров вам нужно написать много кода.
3. Использование кортежа
Это лучшее решение на мой взгляд.
4. Несколько карт
Недостаток этого решения состоит в том, что не очевидно, что две карты связаны, из-за программной ошибки две карты могут быть не синхронизированы.
источник
Map<KeyType, Tuple<Value1Type, Value2Type>>
Нет, не просто так
HashMap
. Вам в основном нуженHashMap
ключ от набора значений.Если вы счастливы использовать внешние библиотеки, у Guava есть именно эта концепция
Multimap
с такими реализациями, какArrayListMultimap
иHashMultimap
.источник
ArrayListMultimap
себя ... или просто использовалиHashMap<String, List<Integer>>
или что-то еще. Вам нужно будет создать пустой список каждый раз, когда значение добавляется в первый раз, в основном.HashMap<String, List<Integer>>
Другим хорошим выбором является использование MultiValuedMap от Apache Commons. Взгляните на Все известные классы реализации в верхней части страницы для специализированных реализаций.
Пример:
может быть заменено на
Так,
приведет к коллекции,
coll
содержащей «A», «B» и «C».источник
Взгляните на
Multimap
guava-библиотеки и их реализацию -HashMultimap
источник
Я использую
Map<KeyType, Object[]>
для связывания нескольких значений с ключом в карте. Таким образом, я могу хранить несколько значений разных типов, связанных с ключом. Вы должны позаботиться о поддержании правильного порядка вставки и извлечения из Object [].Пример. Предположим, мы хотим хранить информацию об ученике. Ключ - это идентификатор, в то время как мы хотели бы сохранить имя, адрес и адрес электронной почты, связанные со студентом.
источник
источник
Для справки, чистым решением JDK8 было бы использование
Map::compute
метода:Такие как
с выходом:
Обратите внимание, что для обеспечения согласованности в случае, если несколько потоков обращаются к этой структуре данных,
ConcurrentHashMap
и,CopyOnWriteArrayList
например, необходимо использовать.источник
computeIfAbsent
.map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
Если вы используете Spring Framework . Существует:
org.springframework.util.MultiValueMap
.Чтобы создать неизменяемую многозначную карту:
Или использовать
org.springframework.util.LinkedMultiValueMap
источник
Да и нет. Решение состоит в том, чтобы создать классы Wrapper для ваших значений, которые содержат 2 (3 или более) значения, которые соответствуют вашему ключу.
источник
Да, это часто называют
multimap
.См. Http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/Multimap.html.
источник
Самый простой способ - использовать библиотеку коллекции Google:
ссылка maven: https://mvnrepository.com/artifact/com.google.collections/google-collections/1.0-rc2
подробнее об этом: http://tomjefferys.blogspot.be/2011/09/multimaps-google-guava.html
источник
Я получил лучшие результаты.
Вам просто нужно создать новый
HashMap
лайкв вашей
for
петле. Он будет иметь тот же эффект, что и тот же ключ и несколько значений.источник
Вывод:
Это библиотека Google-Guava для служебных функций. Это необходимое решение.
источник
Я не смог опубликовать ответ на комментарий Павла, поэтому я создаю новый комментарий для Видхи здесь:
Wrapper будет
SuperClass
для двух классов, которые мы хотим сохранить в качестве значения.а внутри класса-обертки мы можем поместить ассоциации в качестве объектов переменных экземпляра для двух объектов класса.
например
и в HashMap мы можем положить таким образом,
WrapperObj будет иметь переменные класса:
class1Obj, class2Obj
источник
Вы можете сделать это неявно.
Это очень просто и эффективно. Если вы хотите использовать значения разных классов, вы можете сделать следующее:
источник
Это можно сделать с помощью identityHashMap, при условии, что сравнение ключей будет выполнено оператором ==, а не equals ().
источник
Я предпочитаю следующее, чтобы хранить любое количество переменных без необходимости создавать отдельный класс.
источник
Я так привык просто делать это с помощью словаря данных в Objective C. Было сложнее получить подобный результат в Java для Android. В итоге я создал собственный класс, а затем просто создал хэш-карту своего пользовательского класса.
источник
Мы можем создать класс, имеющий несколько ключей или значений, и объект этого класса можно использовать в качестве параметра на карте. Вы можете обратиться к https://stackoverflow.com/a/44181931/8065321
источник
Использование Java Collectors
где отдел твой ключ
источник
Попробуйте LinkedHashMap , пример:
вывод:
источник
linked
больше не будет существовать на карте, потому что вы заменили его наhash
.