У меня есть HashMap, где ключ - это вид птицы, а значение - количество восприятий. Вот мой код:
public class Program {
public static void main(String[] args) {
HashMap<String, Integer> species = new HashMap<>();
Scanner reader = new Scanner(System.in);
species.put("hawk (buteo jamaicensis)", 2);
species.put("eagle (aquila chrysaetos)", 4);
species.put("sparrow (passeridae)", 5);
System.out.println("What specie?"); //output "chicken"
String specie = reader.nextLine();
for (HashMap.Entry<String, Integer> entry: species.entrySet()) {
if (entry.getKey().contains(specie)) {
System.out.println(entry.getKey()+" : "+entry.getValue()+" perceptions");
} else {
System.out.println("Not in database!");
}
}
}
}
Как я могу проверить, существует ли вид в hashmap? Например, если выводится «цыпленок» и его нет в базе данных, программа должна напечатать «Нет в базе данных!». Теперь вывод:
Not in database!
Not in database!
Not in database!
И моя цель:
Not in database!
почему бы просто не вызвать map.get и проверить, существует ли возвращаемое значение
Где вы видите здесь "курицу": species.put("hawk (buteo jamaicensis)", 2); species.put("eagle (aquila chrysaetos)", 4); species.put("sparrow (passeridae)", 5);?
@davidxxx Вот почему ожидаемый результат - «Нет в базе данных!»
Многие люди, похоже, упускают тот факт, что OP (по-видимому, намеренно) проверяет, содержит ли каждый ключ String входную строку, а не просто проверяет, равны ли они.
@Dukeling В любом случае, это бессмысленно. Если OP добавляет на карту три записи, мы ожидаем, что в любом случае будет 3 println. Я голосую за закрытие.
@Dukeling, какой смысл проверять, присутствует ли ключ подстроки на карте, и отвечать с этим? Я думаю, вы упускаете суть.
Примечание: «виды» - единственное число от «видов».
Вы должны пересмотреть: обязательно ли доступ к вашей хэш-карте использовать полное имя (обычный английский плюс латинский), или просто общее имя, или, может быть, только латинское имя? Возможно, вы захотите сопоставить и английское, и латинское имя с объектом Bird, где вы сохраните оба термина (и, возможно, больше) в качестве полей.
Обратите внимание, что даже латинские имена не являются тем, что демонстрирует ваш пример. Воробей может быть «домашним прохожим» или «прохожим монтанусом» - так что же должна делать ваша процедура поиска?




Используйте для этого логический флаг:
boolean found = false;
for (HashMap.Entry<String, Integer> entry: species.entrySet()) {
if (entry.getKey().contains(specie)) {
System.out.println(entry.getKey()+" : "+entry.getValue()+" perceptions");
found = true;
}
} //Loop ends
if (!found) {
System.out.println("Not in database!");
}
Вы также можете использовать для этого Потоки Java 8: (хотя я бы, вероятно, просто рекомендовал вместо этого цикл for)
Optional<Map.Entry<String, Integer>> match =
species.entrySet().stream().filter(entry -> entry.getKey().contains(specie)).findAny();
if (match.isPresent())
System.out.println(match.get().getKey()+" : "+match.get().getValue()+" perceptions");
else
System.out.println("Not in database!");
.stream превращает набор записей в поток.
.filter удаляет все, кроме элемента, который мы ищем.
.findAny возвращает элемент, если он существует.
Хотя, если вы просматриваете карту в цикле, чтобы найти то, что ищете, это подрывает цель карты, и вы можете выбрать список какого-то настраиваемого класса, разделив строку на 2, а затем имея ключом может быть общепринятое английское имя (как рекомендовано в комментариях) или использование более сложной структуры данных, которая позволяет осуществлять эффективный поиск подстроки, например суффиксное дерево.
Я думаю, что стримы для этого - излишество.
if (species.containsKey(selectedSpecie)) {
return species.get(selectedSpecie);
} else {
throw new IllegalStateException("Not in database!");
}
Почему вы перебираете все записи HashMap, если можно просто вызвать
containsKey?