Вывод всех значений HashMap
Добрый день. Программа должна выдавать ключ и несколько значений по этому ключу, но значения выводятся в виде кода: [
public class Task2 < public static void main(String[] args) < Map> personPhone = new HashMap>(); personPhone.put(new Person("Иван", "Иванов"), Arrays.asList(new Phone(88002000500L), new Phone(88002000500L))); System.out.println(Arrays.asList(personPhone)); > > class Phone < public long numberPhone; public Phone(long numberPhone) < this.numberPhone = numberPhone; >> class Person < public String name; public String lastName; public Person(String name, String lastName) < this.name = name; this.lastName = lastName; >>
Отслеживать
задан 20 дек 2016 в 10:27
51 1 1 серебряный знак 4 4 бронзовых знака
у вас не переопределен метод toString(а так же hasdCode и equals)
20 дек 2016 в 10:32
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
В класс Person и Phone добавить метод toString()
@Override public String toString()
@Override public String toString()
Или обработайте Map циклом:
for (Entry> entry : personPhone.entrySet()) < Person person = entry.getKey(); Listphones = entry.getValue(); . Распечатываем удобным способом >
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.
Мапы — Java: Коллекции
Вместо этого можно использовать одну из реализаций – HashMap , которая позволяет хранить пары ключей и значений.
// Создаем новый экземпляр MapString, String> cars = new HashMap<>(); // метод put() добавляет в словарь пару ключ-значение cars.put("O023TO198", "Volvo"); cars.put("O025XE777", "Nissan"); cars.put("O001OO777", "BMW"); System.out.println(cars); // => // Теперь определить марку автомобиля по его номеру значительно проще // метод get() возвращает значение по ключу String modelFromMap = cars.get("O023TO198"); System.out.println(modelFromMap); // "Volvo" System.out.println(cars.get("O025XE700")); // null // key может быть null cars.put(null, "Lada"); System.out.println(cars); // => // замена одного значения на другое cars.put("O025XE777", "Audi"); System.out.println(cars); // =>
Базовые операции с Map
MapString, Integer> people = new HashMap<>(); // Добавление элемента в словарь people.put("Max", 2006); people.put("Petr", 1998); people.put("Ivan", 1981); System.out.println(people); // => System.out.println("Размер Map: " + people.size()); // => Размер Map: 3 MapString, Integer> additionalPeopleMap = new HashMap<>(); additionalPeopleMap.put("Vladimir", 1978); additionalPeopleMap.put("Robert", 2010); additionalPeopleMap.put("Ibrahim", 2011); // Метод putAll() копирует все значения из переданного словаря в текущий people.putAll(additionalPeopleMap); System.out.println(people); // => // Проверка на наличие в словаре ключа System.out.println(people.containsKey("Max")); // => true // и значения System.out.println(people.containsValue(2021)); // => false // Удаление элемента из словаря people.remove("Robert"); System.out.println(people); // => // Удаление всех элементов people.clear(); System.out.println(people); // => <>
Map.Entry
Map.Entry – это интерфейс, который позволяет нам получить доступ к записям в словаре
MapString, String> students = new HashMap<>(); students.put("Max", "Maximov"); students.put("Petr", "Petrov"); students.put("Ivan", "Ivanov"); System.out.println(students.entrySet()); // => [Max=Maximov, Petr=Petrov, Ivan=Ivanov] // 1 способ получения значения по ключу // for (String s : students.keySet()) // String lastname = students.get(s); // > // 2 cпособ получения значения по ключу - более употребим for (Map.EntryString, String> student: students.entrySet()) System.out.println( "Student name is color: #000000;font-weight: bold">+ student.getKey() + " and student lastname is color: #000000;font-weight: bold">+ student.getValue() ); >
Коллекции, реализующие интерфейс Map
// Класс LinkedHashMap MapString, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("Egor", "Yakovlev"); linkedHashMap.put("Max", "Maximov"); linkedHashMap.put("Ivan", "Ivanov"); System.out.println(linkedHashMap); // => // Класс TreeMap MapInteger, ListString>> treeMap = new TreeMap<>(Comparator.reverseOrder()); treeMap.put(23, List.of("Victor", "Ivan")); treeMap.put(18, List.of("Eugene")); treeMap.put(40, List.of("Anna", "Henry", "Igor")); System.out.println(treeMap); // => treeMap.put(35, List.of("Vera")); System.out.println(treeMap);
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Как вывести ключи в Java Map иным способом?
Выводим ключи способом, который видно выше. Но есть способ для ключа и значения в виде:
map.forEach((k, v) -> System.out.println("Key: " + k + " Value: " + v));
Можно ли с его помощью вывести только k(ключ) или v(значение) ?? Ибо если попробовать так:
map.forEach((k) -> System.out.println(k));
то вылетает ошибка
error: incompatible types: incompatible parameter types in lambda expression map.forEach((k) -> System.out.println(k)); ^
- Вопрос задан более трёх лет назад
- 1254 просмотра
1 комментарий
Простой 1 комментарий
Сергей Горностаев @sergey-gornostaev Куратор тега Java
И в чём проблема? Что мешает передать BiFunction в forEach, но в println использовать только k или только v?
Решения вопроса 1
Денис Загаевский @zagayevskiy Куратор тега Java
Android developer at Yandex
Вот что бывает, когда не понимаешь смысл кода, который копируешь.
(k, v) -> .
это лямбда, синтаксический сахар для реализации функциональных интерфейсов(таких интерфейсов, в которых один абстрактный метод).
Map::foreach как раз и принимает такой интерфейс
BiConsumer с методом void accept(T t, U u)
Таким образом, имена k, v всего лишь параметры лямбды, они могут быть любыми. И лямбда, как реализация метода accept интерфейса BiConsumer, должна принимать два аргумента.
Ты можешь их не использовать, если они тебе не нужны.