#java #map #iterator #set
#java #словарь #итератор #установить
Вопрос:
В этой задаче мне нужно найти все совпадающие сопоставления ключей и значений в двух картах, а затем вернуть их на новую карту, но я сталкиваюсь с некоторыми проблемами. Моя идея состоит в том, чтобы найти все совпадающие ключи из двух карт, а затем использовать эти ключи для ссылки на значения. Если бы значения совпадали, я бы поместил ключ / значение в карту. Я пытаюсь выяснить, почему он просто добавляет все общие ключи; он добавляет эти ключи только в том случае, если его соответствующие значения тоже совпадают. Спасибо.
Приглашение:
Напишите метод intersect, который принимает два отображения строк в целые числа в качестве параметров и возвращает новое отображение, содержимое которого является пересечением двух. Пересечение двух карт определяется здесь как набор ключей и значений, которые существуют в обеих картах. Итак, если какой-то ключ K сопоставляется со значением V как в первой, так и во второй карте, включите его в свой результат. Если K не существует в качестве ключа в обеих картах или если K не соответствует одному и тому же значению V в обеих картах, исключите эту пару из вашего результата. Например, рассмотрим следующие две карты:
{Janet=87, Logan=62, Whitaker=46, Alyssa=100, Stefanie=80, Jeff=88, Kim=52, Sylvia=95}
{Logan=62, Kim=52, Whitaker=52, Jeff=88, Stefanie=80, Brian=60, Lisa=83, Sylvia=87}
Вызов вашего метода на предыдущих картах вернет следующую новую карту (порядок пар ключ / значение не имеет значения):
{Logan=62, Stefanie=80, Jeff=88, Kim=52}
Мой код:
// we need to store the keys, then get the values in common, then put the key/map into map
public static Map<String, Integer> intersect(Map<String, Integer> first, Map<String, Integer> second) {
Map<String, Integer> output = new HashMap<String, Integer>(first); // combined output
Set<String> keyFirst = new HashSet<String>(); // stores all the keys for first
for (String key: first.keySet()) { // goes through each key in input
keyFirst.add(key); // adds all keys from first into keyFirst
}
// goes through each key in common and checks to see if they reference to the same value
Iterator<String> keyFirstItr = keyFirst.iterator();
while (keyFirstItr.hasNext()) {
String keyTemp = keyFirstItr.next();
if (first.get(keyTemp) == second.get(keyTemp)) { // If same key, same value mapped
output.put(keyTemp, first.get(keyTemp)); // add key value to map
}
}
return output;
}
Комментарии:
1. В чем ваш вопрос? С чем вы сравниваете объекты
==
?2. Я пытаюсь выяснить, почему он просто добавляет все общие ключи.
3. Это не вопрос. Это подтверждение. Вопрос заканчивается вопросительным знаком.
Ответ №1:
Вы помещаете все значения из первого в выходной, передавая его конструктору.
Map<String, Integer> output = new HashMap<String, Integer>(first); // you are passing first to the constructor.
Вам не нужно создавать другой набор, метод keySet() возвращает set, поэтому приведенные ниже строки не требуются.
Set<String> keyFirst = new HashSet<String>(); // stores all the keys for first
for (String key: first.keySet()) { // goes through each key in input
keyFirst.add(key); // adds all keys from first into keyFirst
}
Вот правильная реализация.
// we need to store the keys, then get the values in common, then put the key/map into map
public static Map<String, Integer> intersect(Map<String, Integer> first, Map<String, Integer> second) {
Map<String, Integer> output = new HashMap<String, Integer>(); // combined output
// goes through each key in common and checks to see if they reference to the same value
Iterator<String> keyFirstItr = first.keySet().iterator();
while (keyFirstItr.hasNext()) {
String keyTemp = keyFirstItr.next();
if (first.get(keyTemp).equals(second.get(keyTemp))) { // If same key, same value mapped
output.put(keyTemp, first.get(keyTemp)); // add key value to map
}
}
return output;
}
Комментарии:
1. Скажите ему, чтобы он также использовал
equals
, а не==
!2. get возвращает значение, которое является целым числом, поэтому == будет работать
3. @AmitChotaliya: нет, этого не произойдет. == проверяет, указывают ли две ссылки на один и тот же объект.
new Integer(1) == new Integer(1)
равно false.4. @Seelenvirtuose amp; JB Nizet вы правы, я изменю ответ. Разве это не должно выполнять автоматическую упаковку / распаковку здесь?
5. Спасибо за помощь. В книге, которую я имею, говорится, что распаковка происходит автоматически и что «Java понимает взаимосвязь между in и Integer, она развернет для вас целочисленные объекты и предоставит вам значения int, хранящиеся внутри». Приведенный пример был: int product = list.get(0) * list.get(1);
Ответ №2:
Более простое решение этого упражнения — пропустить итератор и использовать цикл for, как показано ниже. Для каждого имени в map1 мы проверяем, существует ли оно в map2 и совпадают ли значения. Затем K и V добавляются к новой карте:
public static Map intersect(Map<String, Integer> map1, Map<String, Integer> map2){
Map<String, Integer> newMap = new HashMap<>();
for (String name : map1.keySet()){
if(map2.containsKey(name) amp;amp; map1.get(name).equals(map2.get(name))){
newMap.put(name, map1.get(name));
}
}
return newMap;
}