Как проверить, существует ли значение в HashMap
у меня есть следующие HashMap
здесь key
- это String
и value
представлен ArrayList
:
HashMap<String, ArrayList<String>> productsMap = AsyncUpload.getFoodMap();
у меня тоже есть другой ArrayList<String> foods
реализовано в моем приложении.
мой вопрос в том, что было бы лучшим способом узнать, если мой HashMap
содержит String
С моей второй ArrayList
?
я безуспешно пытался:
Iterator<String> keySetIterator = productsMap.keySet().iterator();
Iterator<ArrayList<String>> valueSetIterator = productsMap.values().iterator();
while(keySetIterator.hasNext() && valueSetIterator.hasNext()){
String key = keySetIterator.next();
if(mArrayList.contains(key)){
System.out.println("Yes! its a " + key);
}
}
7 ответов
почему бы и нет:
// fast-enumerating map's values
for (ArrayList<String> value: productsMap.values()) {
// using ArrayList#contains
System.out.println(value.contains("myString"));
}
и если вам нужно перебирать все ArrayList<String>
, вместо того, чтобы искать только одно конкретное значение:
// fast-enumerating food's values ("food" is an ArrayList<String>)
for (String item: foods) {
// fast-enumerating map's values
for (ArrayList<String> value: productsMap.values()) {
// using ArrayList#contains
System.out.println(value.contains(item));
}
}
редактировать
в прошлый раз я обновил это с помощью некоторых идиом Java 8.
API потоков Java 8 позволяет более декларативный (и, возможно, элегантный) способ обработки этих типов итерации.
например, вот (немного слишком многословный) способ достижения же:
// iterate foods
foods
.stream()
// matches any occurrence of...
.anyMatch(
// ... any list matching any occurrence of...
(s) -> productsMap.values().stream().anyMatch(
// ... the list containing the iterated item from foods
(l) -> l.contains(s)
)
)
... и вот более простой способ достичь того же самого, первоначально повторяя productsMap
значения вместо содержимого foods
:
// iterate productsMap values
productsMap
.values()
.stream()
// flattening to all list elements
.flatMap(List::stream)
// matching any occurrence of...
.anyMatch(
// ... an element contained in foods
(s) -> foods.contains(s)
)
вам нужно использовать containsKey()
метод. Для этого вы просто получаете hashMap, из которого хотите получить ключ, а затем используете containsKey
метод, который вернет boolean
значение, если это так. Это будет искать весь hashMap без необходимости итерации по каждому элементу. Если у вас есть ключ, вы можете просто получить значение.
Это может выглядеть примерно так:
if(productsMap.values().containsKey("myKey"))
{
// do something if hashMap has key
}
вот ссылка Android
из Android docs:
public boolean containsKey (ключ объекта) добавлен в API уровня 1
возвращает, содержит ли эта карта указанный ключ. Ключ параметров ключ для поиска. Возвращает
true if this map contains the specified key, false otherwise.
попробуйте это :
public boolean anyKeyInMap(Map<String, ArrayList<String>> productsMap, List<String> keys) {
Set<String> keySet = new HashSet<>(keys);
for (ArrayList<String> strings : productsMap.values()) {
for (String string : strings) {
if (keySet.contains(string)) {
return true;
}
}
}
return false;
}
попробуй такое
Iterator<String> keySetIterator = productsMap.keySet().iterator();
Iterator<ArrayList<String>> valueSetIterator = productsMap.values().iterator();
while(keySetIterator.hasNext()){
String key = keySetIterator.next();
if(valueSetIterator.next().contains(key)){ // corrected here
System.out.println("Yes! its a " + key);
}
}
Если вам нужен способ Java 8, вы можете сделать что-то вроде этого:
private static boolean containsValue(final Map<String, ArrayList<String>> map, final String value){
return map.values().stream().filter(list -> list.contains(value)).findFirst().orElse(null) != null;
}
или что-то вроде этого:
private static boolean containsValue(final Map<String, ArrayList<String>> map, final String value){
return map.values().stream().filter(list -> list.contains(value)).findFirst().isPresent();
}
оба должны давать практически одинаковый результат.
вот пример метода, который проверяет оба сценария. Поиск элементов в ключах карты, а также поиск элементов в списках каждой записи карты:
private static void testMapSearch(){
final ArrayList<String> fruitsList = new ArrayList<String>();
fruitsList.addAll(Arrays.asList("Apple", "Banana", "Grapes"));
final ArrayList<String> veggiesList = new ArrayList<String>();
veggiesList.addAll(Arrays.asList("Potato", "Squash", "Beans"));
final Map<String, ArrayList<String>> productsMap = new HashMap<String, ArrayList<String>>();
productsMap.put("fruits", fruitsList);
productsMap.put("veggies", veggiesList);
final ArrayList<String> foodList = new ArrayList<String>();
foodList.addAll(Arrays.asList("Apple", "Squash", "fruits"));
// Check if items from foodList exist in the keyset of productsMap
for(String item : foodList){
if(productsMap.containsKey(item)){
System.out.println("productsMap contains a key named " + item);
} else {
System.out.println("productsMap doesn't contain a key named " + item);
}
}
// Check if items from foodList exits in productsMap's values
for (Map.Entry<String, ArrayList<String>> entry : productsMap.entrySet()){
System.out.println("\nSearching on list values for key " + entry.getKey() + "..");
for(String item : foodList){
if(entry.getValue().contains(item)){
System.out.println("productMap's list under key " + entry.getKey() + " contains item " + item);
} else {
System.out.println("productMap's list under key " + entry.getKey() + " doesn't contain item " + item);
}
}
}
}
вот результат:
productsMap не содержит ключа с именем Apple
productsMap не содержит ключа с именем Squash
productsMap содержит ключ с именем fruits
поиск по значениям списка для основных фруктов..
список productMap под ключевыми фруктами содержит элемент Apple
список productMap под ключевыми фруктами не содержит пункт Squash
список productMap в разделе ключевые фрукты не содержит пункт фрукты
поиск по значениям списка для ключевых овощи..
список productMap под ключевыми овощами не содержит элемент Apple
список productMap под ключевыми овощами содержит пункт Squash
список productMap под ключевыми овощами не содержит пункт фрукты