HashMap Java как добавлять по значению?
Как можно добавить элемент в map по значению? Например, мне нужно написать Имя Вася . Программа посмотрит, если Вася есть, то выведет его Номер и Имя , а если Васи нет, то попросит добавить ему номер и сохранит в map . Я вроде как разобрался как добавлять по номеру, а вот как по имени не могу понять.
public static void main(String[] args) < // командой LIST вывести весь список в алфавитном порядке с номерами // если пользователь пишет номер и он не найден, просит ввести имя, и запоминает номер и имя // если номер найден то выводит информацию (номер) (имя) // если вводишь имя то выводит информацию (номер)(имя) // если такого имени нет то просим ввести номер и запоминаем(имя)(номер) HashMapnumbers2Names = new HashMap<>(); numbers2Names.put(100, "Vasya"); numbers2Names.put(200, "Petya"); numbers2Names.put(300, "Grisha"); numbers2Names.put(400, "Misha"); numbers2Names.put(500, "Pasha"); Scanner scanner = new Scanner(System.in); for (;;) < System.out.println("Plz write command ADD- add new person, LIST - show all persons"); String command = scanner.nextLine(); //вывод всего списка if (command.equals("LIST")) < for (Map.Entryitem : numbers2Names.entrySet()) < System.out.println("Number: " + item.getKey() + " Name: " + item.getValue()); >> //добавление по номеру if (command.equals("ADD")) < String name = ""; int number; System.out.println("Plz write number"); Scanner numScan = new Scanner(System.in); //считываем с консоли номер number = numScan.nextInt(); //сохраняем в переменную //проверяем есть ли уже такой номер, если нет то добавляем if (numbers2Names.containsKey(number)) < // такой номер есть и выводим номер-имя System.out.println("this number exists"); System.out.println("Number: " + number + " Name: " + numbers2Names.get(number)); >else < System.out.println("This new Number, Plz write name this number"); Scanner nameScan = new Scanner(System.in); //считываем с консоли имя name = nameScan.nextLine(); // сохраняем в переменную numbers2Names.put(number, name); //добавляем в hashmap номер и имя System.out.println("person save"); >> >
Отслеживать
задан 2 апр 2021 в 14:13
86 1 1 серебряный знак 7 7 бронзовых знаков
Может сделать ключ и значение String ?
2 апр 2021 в 14:36
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
По заданию вижу, что нужно многое поменять:
- Чтение имени или номера для поиска (сейчас есть только поиск по номеру)
- Проверка существования как номера, так и имени в таблице (сейчас есть проверка только номера)
- Проверка номера или имени при добавлении новой записи (сейчас этого нет)
mainLoop: for (; ; ) < System.out.println("Plz write command ADD- add new person, LIST - show all persons"); String command = scanner.nextLine(); //вывод всего списка if (command.equals("LIST")) < for (Map.Entryitem : numbers2Names.entrySet()) < System.out.println("Number: " + item.getKey() + " Name: " + item.getValue()); >> //добавление по номеру if (command.equals("ADD")) < System.out.println("Plz write number or name"); Scanner numScan = new Scanner(System.in); //считываем с консоли номер String name = numScan.next(); //сохраняем в переменную Integer number = null; // пробуем понять, что это число try < number = Integer.parseInt(name); // есть номер существует в таблице, то выводим результат if (numbers2Names.containsKey(number)) < // такой номер есть и выводим номер-имя System.err.println("This number exists"); System.err.println("Number: " + number + " Name: " + numbers2Names.get(number)); continue ; >> catch (NumberFormatException e) < // если имя существует в таблице, то выводим результат if (numbers2Names.containsValue(name)) < for (Map.Entryentry : numbers2Names.entrySet()) < if(entry.getValue().equals(name)) < System.err.println("This name exists"); System.err.println("Number: " + entry.getKey() + " Name: " + entry.getValue()); continue mainLoop; >> > > // если ни номера, ни имени не существует в таблице, то добавляем значение if(number != null) < System.out.println("This new Number, Plz write name this number"); Scanner nameScan = new Scanner(System.in); //считываем с консоли имя name = nameScan.nextLine(); // сохраняем в переменную if (numbers2Names.containsValue(name)) < System.err.println("Name already exists"); >else < numbers2Names.put(number, name); //добавляем в hashmap номер и имя >> else < System.out.println("This new Name, Plz write number this name"); Scanner nameScan = new Scanner(System.in); //считываем с консоли число number = Integer.parseInt(nameScan.nextLine()); // сохраняем в переменную if (numbers2Names.containsKey(number)) < System.err.println("Number already exists"); >else < numbers2Names.put(number, name); //добавляем в hashmap номер и имя >> > >
Отслеживать
ответ дан 2 апр 2021 в 16:46
18.1k 24 24 серебряных знака 49 49 бронзовых знаков
Спасибо.Я еще try catch не проходил, но ваш вариант работает, есть идея сделать Map где ключ и значение будут String и проверять уже их.
2 апр 2021 в 17:47
@porosenok в данном примере try catch это небольшой трюк, конструкция используется не совсем по назначению)
2 апр 2021 в 21:51
Поменяй местами номер с именем Map
И потом (if !map.containsKey(name)
Для того чтобы значения в коллекции были как и ключи, уникальными, есть два способа. Насчет первого: вы можете использовать библиотеку guava и BiMap оттуда — она гарантирует не только уникальность ключей, но и значений, более того, ключ можно получить из нее по значению. Документация : https://www.tutorialspoint.com/guava/guava_bimap.htm
Второй вариант, это перед вставкой проверять, есть ли такое имя, в этом поможет метод containsValue() , и если содержит, то получить пару, например:
String targetName = "Ivan" ; if(map.containsValue(targetName)) < for(Map.Entryentry : map.entrySet()) < if(entry.getValue().equals(targetName)< //some logic >> >
Можно так же заменить на стримы и optional:
map.stream() .map(Map::entrySet) .filter(entry - > entry.getValue().equals(targetName)) . orElseGet(() - > //insert) ;
Как то так. Не факт что без ошибок) в среде удобнее чем с телефона
HashMap
При работе с массивами я сравнивал их с коробочками. Слово HashMap содержит слово map — карта. Только это не пытайтесь найти сходство с картами в географическом атласе, с гуглокартами, с Яндекс.Картами или, на худой конец, с игральными картами. Это карточка в картотеке. Вы заполняете карточки какими-то данными и кладёте их в ящик. Если вы содержите гостиницу для котов, то скорее всего вы занесёте в карточку имя кота, возраст и т.п.
Класс HashMap использует хеш-таблицу для хранения карточки, обеспечивая быстрое время выполнения запросов get() и put() при больших наборах. Класс реализует интерфейс Map (хранение данных в виде пар ключ/значение). Ключи и значения могут быть любых типов, в том числе и null. При этом все ключи обязательно должны быть уникальны, а значения могут повторяться. Данная реализация не гарантирует порядка элементов.
Общий вид HashMap:
// K - это Key (ключ), V - Value (значение) class HashMap
Объявить можно следующим образом:
Map hashMap = new HashMap(); // или так Map hashMap = new HashMap();
По умолчанию при использовании пустого конструктора создается картотека ёмкостью из 16 ячеек. При необходимости ёмкость увеличивается, вам не надо об этом задумываться.
Вы можете указать свои ёмкость и коэффициент загрузки, используя конструкторы HashMap(capacity) и HashMap(capacity, loadFactor). Максимальная ёмкость, которую вы сможете установить, равна половине максимального значения int (1073741824).
Добавление элементов происходит при помощи метода put(K key, V value). Вам надо указать ключ и его значение.
hashMap.put("0", "Васька");
hashMap.size();
Проверяем ключ и значение на наличие:
hashMap.containsKey("0"); hashMap.containsValue("Васька");
Выбираем все ключи:
for (String key : hashMap.keySet())
Выбираем все значения:
for (int value : hashMap.values())
Выбираем все ключи и значения одновременно:
for (Map.Entry entry : hashMap.entrySet())
Пример первый
// Создадим хеш-карточку Map hashMap = new HashMap<>(); // Помещаем данные на карточку hashMap.put("Васька", 5); hashMap.put("Мурзик", 8); hashMap.put("Рыжик", 12); hashMap.put("Барсик", 5); // Получаем набор элементов Set set = hashMap.entrySet(); // Отобразим набор for (Map.Entry me : set) < System.out.print(me.getKey() + ": "); System.out.println(me.getValue()); >// Добавляем значение int value = hashMap.get("Рыжик"); hashMap.put("Рыжик", value + 3); System.out.println("У Рыжика стало " + hashMap.get("Рыжик"));
Если вы посмотрите на результат, то увидите, что данные находятся не в том порядке, в котором вы заносили. Второй важный момент — если в карточке уже существует какой-то ключ, то если вы помещаете в него новое значение, то ключ перезаписывается, а не заносится новый ключ.
В древних версиях Java приходилось добавлять новые значения следующим образом.
hashMap.put("Мурзик", new Integer(8)); // или hashMap.put("Мурзик", Integer.valueOf(8));
Потом Java поумнела и стала самостоятельно переводить число типа int в объект Integer. Но это не решило основной проблемы — использование объектов очень сильно сказывается на потреблении памяти. Поэтому в Android были предложены аналоги этого класса (см. ниже). Ключом в Map может быть любой объект, у которого корректно реализованы методы hashCode() и equals().
Пример второй
Так как ключи являются уникальными, мы можем написать следующую программу — сгенерируем набор случайных чисел сто раз и посчитаем количество повторов. Map легко решит эту задачу — в качестве ключа используется сгенерированное число, а в качестве значения — количество повторов.
Random random = new Random(36); Map hashMap = new HashMap<>(); for (int i = 0; i < 100; i++)< // Создадим число от 0 до 10 int number = random.nextInt(10); Integer frequency = hashMap.get(number); hashMap.put(number, frequency == null ? 1 : frequency + 1); >System.out.println(hashMap);
Метод get() возвращает null, если ключ отсутствует, т.е число было сгенерировано впервые или в противном случае метод возвращает для данного ключа ассоциированное значение, которое увеличивается на единицу.
Пример третий
Пример для закрепления материала. Поработаем с объектами классов. Нужно самостоятельно создать класс Pet и его наследников Cat, Dog, Parrot.
Создадим отображение из домашних животных, где в качестве ключа выступает строка, а в качестве значения класс Pet.
Map hashMap = new HashMap<>(); hashMap.put("Кот", new Cat("Мурзик")); hashMap.put("Собака", new Dog("Бобик")); hashMap.put("Попугай", new Parrot("Кеша")); System.out.println(hashMap); Pet cat = hashMap.get("Кот"); System.out.println(cat); System.out.println(hashMap.containsKey("Кот")); System.out.println(hashMap.containsValue(cat));
Многомерные отображения
Контейнеры Map могут расширяться до нескольких измерений, достаточно создать контейнер Map, значениями которого являются контейнеры Map (значениями которых могут быть другие контейнеры). Предположим, вы хотите хранить информацию о владельцах домашних животных, у каждого из которых может быть несколько любимцев. Для этого нам нужно создать контейнер Map>.
Map> personMap = new HashMap<>(); personMap.put(new Person("Иван"), Arrays.asList(new Cat("Барсик"), new Cat("Мурзик"))); personMap.put(new Person("Маша"), Arrays.asList(new Cat("Васька"), new Dog("Бобик"))); personMap.put(new Person("Ирина"), Arrays.asList(new Cat("Рыжик"), new Dog("Шарик"), new Parrot("Гоша"))); System.out.println("personMap: " + personMap); System.out.println("personMap.keySet(): " + personMap.keySet()); for(Person person : personMap.keySet()) < System.out.println(person + " имеет"); for (Pet pet : personMap.get(person))< System.out.println(" " + pet); >>
Метод keySet() возвращает контейнер Set, содержащий все ключи из personMap, который используется в цикле для перебора элементов Map.
Sparse arrays — аналог в Android
Разработчик Android посчитали, что HashMap не слишком оптимизирован для мобильных устройств и предложили свой вариант в виде специальных массивов. Данные классы являются родными для Android, но не являются частью Java. Очень рекомендуют использовать именно Android-классы. Не все программисты знают об этих аналогах, а также классический код может встретиться в различных Java-библиотеках. Если вы увидите такой код, то заменить его на нужный. Ниже представлена таблица для замены.
HashMap | Array class |
---|---|
HashMap | ArrayMap |
HashMap | SparseArray |
HashMap | SparseBooleanArray |
HashMap | SparseIntArray |
HashMap | SparseLongArray |
HashMap | LongSparseArray |
Существует ещё класс HashTable, который очень похож в использовании как и HashMap.
shcherbakoff / Solution.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
package com . javarush . test . level08 . lesson03 . task05 ; |
import java . util . HashMap ; |
import java . util . Map ; |
/* Вывести на экран список значений |
Есть коллекция HashMap, туда занесли 10 различных строк. |
Вывести на экран список значений, каждый элемент с новой строки. |
*/ |
public class Solution |
public static void main ( String [] args ) throws Exception |
HashMap < String , String >map = new HashMap < String , String >(); |
map . put ( «Sim» , «Sim» ); |
map . put ( «Tom» , «Tom» ); |
map . put ( «Arbus» , «Arbus» ); |
map . put ( «Baby» , «Baby» ); |
map . put ( «Cat» , «Cat» ); |
map . put ( «Dog» , «Dog» ); |
map . put ( «Eat» , «Eat» ); |
map . put ( «Food» , «Food» ); |
map . put ( «Gevey» , «Gevey» ); |
map . put ( «Hugs» , «Hugs» ); |
printValues ( map ); |
> |
public static void printValues ( Map < String , String >map ) |
for ( Map . Entry < String , String >pair : map . entrySet ()) |
String value = pair . getValue (); |
System . out . println ( value ); |
> |
> |
> |
HashMap вывод значений и преобразование в Сет
Вопрос такой в чем разница и как правильнее , если я хочу вывести все значения:
1 2 3
for(Map.Entry entry : phones.entrySet()){ System.out.println(entry.getValue()); }
1 2 3
for (String s: phones.values()){ System.out.println(s); }
И второй вопрос, чтобы все значения кинут в Сет, так правильно или надо как то через Map.Entry?
1 2 3 4
SetString> set = new HashSet<>(); for (String s: phones.values()){ set.add(s); }
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Вывод числовых значений из БЗ и преобразование в текстовые значения
Всем привет! Есть функция, которая отвечает за вывод единиц измерений товара <p>Единицы.
Вывод значений повышенной точности. Преобразование многобитного двоичного числа в десятичное
Здравствуйте! Хотелось бы узнать как осуществляется вывод значений повышенной точности и.
HashMap для нескольких значений
Использую такой метод для того чтобы в базе найти нужную мне строчку по айди предмета. Но вот.
Вывод содержимого HashMap
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;.
Исправить вывод из HashMap
вот код. import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList;.