次のHashMap
があります。key
はString
であり、value
はArrayList
で表されます。
HashMap<String, ArrayList<String>> productsMap = AsyncUpload.getFoodMap();
また、アプリケーションに別のArrayList<String> foods
を実装しています。
私の質問は、私のHashMap
に2番目の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);
}
}
何故なの:
// fast-enumerating map's values
for (ArrayList<String> value: productsMap.values()) {
// using ArrayList#contains
System.out.println(value.contains("myString"));
}
そして、特定の1つの値のみを探すのではなく、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イディオムで更新しました。
Java 8ストリームAPIは、これらのタイプの反復を処理する、より宣言的な(そして間違いなくエレガントな)方法を可能にします。
たとえば、同じことを実現する(少し冗長すぎる)方法を次に示します。
// 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;
}
hashMap.containsValue("your value");
HashMapに値が含まれているかどうかを確認します
両方のシナリオをテストするサンプルメソッドを次に示します。マップのキー内のアイテムを検索し、各マップエントリのリスト内のアイテムも検索します。
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のリストにアイテムフルーツが含まれていません
これを試して
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();
}
どちらもほぼ同じ結果を生成するはずです。