Java 检查列表是否是HashMap中的值
我想检查一个值是否存在 我的代码:Java 检查列表是否是HashMap中的值,java,list,hashmap,Java,List,Hashmap,我想检查一个值是否存在 我的代码: public static final Map<String, List<String>> m = new HashMap<>(); if(m.containsValue("gummi")) {...} publicstaticfinalmap m=newhashmap(); 如果(m.containsValue(“gummi”){…} 我的问题是,该值是一个列表。 如何查看列表?引用Javadoc: 换句话说,如果两
public static final Map<String, List<String>> m = new HashMap<>();
if(m.containsValue("gummi")) {...}
publicstaticfinalmap m=newhashmap();
如果(m.containsValue(“gummi”){…}
我的问题是,该值是一个列表。
如何查看列表?引用Javadoc:
换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等
因此,要检查值是否存在,可以创建一个列表并使用该列表调用,因为此方法将调用equals
,以确定相等性。如果相同元素的顺序相同,则会找到匹配项
您可以使用以下参数从值数组轻松创建列表
:
示例代码:
Map<String, List<String>> m = new HashMap<>();
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
m.put("key", list);
if (m.containsValue(Arrays.asList("1", "2"))) {
System.out.println("contains value");
}
Map m=newhashmap();
列表=新的ArrayList();
列表。添加(“1”);
列表。添加(“2”);
m、 放置(“键”,列表);
if(m.containsValue(Arrays.asList(“1”、“2”)){
System.out.println(“包含值”);
}
因此我将把这个问题解释为想要告诉映射的任何值是否包含目标字符串
可能有一种更合适的第三方双向多重映射实现。如果您将来阅读本文,那么这种类型可能在JavaSE中-请编辑此答案
给定数据结构,这将需要搜索整个数据。最好用另一种方式进行Map
映射。让我们忽略这一点
streams一行表达式解决方案:
m.values().stream().anyMatch(list -> list.contains("gummi"))
编辑:对于马的声音,非流式版本
flatContains(m.values(), "gummi")
在哪里
公共静态布尔值(
Iterable>集合,
对象值
) {
用于(集合:集合){
if(collection.contains(value)){
返回true;
}
}
返回false;
}
通常避免流会使代码更具可读性(更快)。然而,在这种情况下,我会直奔溪流。如果涉及到flatMap
,选择就会更加接近
Map<String, List<String>> m = new HashMap<>();
List<String> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<String> list3 = new ArrayList<>();
m.put("1", list1);
m.put("2", list2);
System.out.println(m.containsValue(list1));
System.out.println(m.containsValue(list2));
System.out.println(m.containsValue(list3));
解释
只要新列表为空,hashcode值始终为1。因此list1、list2和list3的hashcode值都为1。基本意思是,
list1 = list2 = list3
所以即使我们检查m.containsValue(列表3);它将返回true。但如果列表不是空的,则每个列表都将具有唯一的哈希代码。所以,只要您有一个带有非空列表的映射,那么我们就可以使用containsValue(listObject),它将返回正确的结果。下面的例子
Map<String, List<String>> m = new HashMap<>();
List<String> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<String> list3 = new ArrayList<>();
list1.add("apple");
list1.add("orange");
list2.add("mobile");
list2.add("computer");
m.put("1", list1);
m.put("2", list2);
System.out.println(m.containsValue(list1));
System.out.println(m.containsValue(list2));
System.out.println(m.containsValue(list3));
其他用例:
如果我们想检查映射中的值是否为list类型,或者我们想检查某个值是否存在于其中一个列表中,那么我们可以如下迭代映射
for (String key : m.keySet()) {
if (m.get(key) instanceof List) {
for (String listItem : m.get(key)) {
if ("valueWeSearchFor".equalsIgnoreCase(listItem)) {
break;
}
}
}else{
//If the value in the map is not of type list
//What to do!!
}
}
@Tom的答案是最好的,@horsesvoice询问Java 7版本,如下所示:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* https://stackoverflow.com/questions/32925049/check-if-a-list-is-a-value-in-a-hashmap
*
* @author surender.kumar
*/
public class CheckListValueInHashMapExists {
public static final Map<String, List<String>> m = new HashMap<>();
public static void main(String[] args) {
System.out.println("Running main ...");
initM();
String gummi = "gummi";
System.out.println("Do the list contains value gummi? " + checkValueExistsJava7());
}
private static boolean checkValueExistsJava7() {
for (List<String> list : m.values()) {
if (list.contains("gummi")) {
return true;
}
}
return false;
}
private static void initM() {
List<String> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
list1.add("value1a");
list1.add("value1b");
list2.add("value2");
list2.add("gummi");
m.put("1", list1);
m.put("2", list2);
}
}
hashMap是键值存储,当您想在值中搜索值时速度很慢,所以首先要规范化您的映射,使其类似于键值和值的交换
Map<String, String> searchMap = m.entrySet().stream()
.flatMap(entry -> entry.getValue().stream().map(etn -> new AbstractMap.SimpleEntry<>(etn, entry.getKey())))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
现在mkey是原始地图键。if为null不存在于原始映射中的任何值中,您可以像if键不为null这样访问已建立的列表
List<String> mValue = m.get(mkey);
List mValue=m.get(mkey);
Java7:包含Map的
假设与Tom相同,下面是一个Java 7版本(根据要求):
缓存有点难;我们需要反转地图:
// Cached version
private Map<String, List<String>> valueKeys = invert(map);
private Map<String, List<String>> invert(Map<String, List<String>> map) {
Map<String, List<String>> result = new HashMap<>();
for (Entry<String, List<String>> entry : map.entrySet()) {
for (value : entry.getValue()) {
List<String> keys;
if (result.containsKey(value)) {
keys = result.get(value);
} else {
keys = new ArrayList<String>();
result.put(value, keys);
}
keys.add(entry.getKey());
}
}
return result;
}
static List<String> keysForValue(String value) {
return valueKeys.get(value);
}
//缓存版本
私有映射valueKeys=反转(映射);
私有映射反转(映射映射){
映射结果=新的HashMap();
for(条目:map.entrySet()){
对于(值:entry.getValue()){
列出键;
if(结果容器(值)){
keys=result.get(值);
}否则{
keys=newarraylist();
结果。输入(值、键);
}
key.add(entry.getKey());
}
}
返回结果;
}
静态列表keysForValue(字符串值){
返回valueKeys.get(值);
}
我认为Surender Kherwa的答案是合适的,但我认为当您在集合中查找元素时,最好使用while
循环,而不是for
,下面是一个示例(针对java 7):
String gummi=“gummi”;
Map Map=newhashmap(){
{
put(“键1”,新数组列表(){{
添加(“支票”);
添加(“如果”);
添加(“a”);
添加(“列表”);
添加(“is”);
}});
put(“键2”,新数组列表(){{
添加(“a”);
添加(“gummi”);
增加(“价值”);
添加(“in”);
添加(“a”);
}});
put(“键3”,新数组列表(){{
添加(“HashMap”);
添加(“java”);
添加(“7”);
添加(“while”);
添加(“循环”);
添加(“版本”);
}});
}};
迭代器迭代器=map.entrySet().Iterator();
while(iterator.hasNext()){
Map.Entry=iterator.next();
if(entry.getValue().contains(gummi)){
System.out.println(“在“+entry.getKey()”中找到);
打破
}
}
如果值是列表,则可以使用列表的contains方法检查
列表具有所需的字符串
public static void main(String args[]){
public static final Map<String, List<String>> m = new HashMap<>();
checkStringInMapOfLists("gummi",m);
}
publicstaticvoidmain(字符串参数[]){
publicstaticfinalmap m=newhashmap();
勾选线(gummi,m);
}
下面的方法迭代hashmap中的值,并检查hashmap中的任何列表是否包含所需的字符串
private boolean checkStringInMapOfLists(String input,Map<String, List<String>> m){
for(List<String> list : m.values()){
if(list.contains(input))
return true;
}
return false;
}
private boolean checkStringInMapflists(字符串输入,映射m){
对于(列表:m.values()){
if(列表包含(输入))
返回true;
}
返回false;
}
我使用java 8检查了两个场景。下面的分析是针对最坏情况的
场景1:地图包含1000000个密钥
在这种情况下,java流API似乎比循环慢。地图包含1000000个键。这些数据流花费了107543400纳秒来完成任务。循环时间为73688600纳秒。然而,并行流只需要51464500纳秒
签出下面的解决方案代码
public static void main(String[] args) {
try {
App app = new App();
String parameter = "invalid value";
int numberOfKeys = 1000000;
Map<String, List<String>> m = new HashMap<>();
// adding values to map
for (int i = 0; i < numberOfKeys ; i++) {
m.put(i + "",
Arrays.asList(i * 10 + "", i * 11 + "", i * 12 + "", i * 13 + "", i * 14 + "", i * 15 + ""));
}
/** check time difference **/
System.out.println("Loops");
long begin = System.nanoTime();
boolean b = app.containsValue_loops(m, parameter);
System.out.println(System.nanoTime() - begin);
System.out.println(b);
System.out.println("\nJava 8 - stream");
begin = System.nanoTime();
boolean a = app.containsValue_java8(m, parameter);
System.out.println(System.nanoTime() - begin);
System.out.println(a);
System.out.println("\nJava 8 - parallel stream");
begin = System.nanoTime();
boolean c = app.containsValue_java8_parallel(m, parameter);
System.out.println(System.nanoTime() - begin);
System.out.println(c);
} catch (Exception e) {
System.out.println(e);
}
}
/** Checks parameter contains in the list using loops **/
public boolean containsValue_loops(Map<String, List<String>> m, String parameter) {
for (List<String> list : m.values()) {
if (list.contains(parameter)) {
// return immediately if value contains in the list
return true;
}
}
return false;
}
/** Checks parameter contains in the list using streams **/
public boolean containsValue_java8(Map<String, List<String>> m, String parameter) {
return m.values().stream().anyMatch(list -> list.contains(parameter));
}
/** Checks parameter contains in the list using parallel streams **/
public boolean containsValue_java8_parallel(Map<String, List<String>> m, String parameter) {
return m.values().parallelStream().anyMatch(list -> list.contains(parameter));
}
场景2:地图仅包含10K
String mkey = searchMap.get("gummi");
List<String> mValue = m.get(mkey);
// Live version
static boolean contains(Map<String, List<String>> map, String value) {
for (List<String> list : map.values()) {
if(list.contains(value)) return true;
}
return false;
}
// Cached version
private List<String> allValues = getInnerValues(map);
private List<String> getInnerValues(Map<String, List<String>> map) {
List<String> result = new ArrayList<>();
for (List<String> list : map.values()) {
result.addAll(list);
}
return result;
}
static boolean contains(String value) {
return allValues.contains(value);
}
// Live version
static String anyKeyForValue(Map<String, List<String>> map, String value) {
for (Entry<String, List<String>> entry : map.entrySet()) {
if(entry.getValue().contains(value)) return entry.getKey();
}
return null;
}
static List<String> keysForValue(Map<String, List<String>> map, String value) {
List<String> result = new ArrayList<>();
for (Entry<String, List<String>> entry : map.entrySet()) {
if(entry.getValue().contains(value)) result.add(entry.getKey());
}
return result;
}
// Cached version
private Map<String, List<String>> valueKeys = invert(map);
private Map<String, List<String>> invert(Map<String, List<String>> map) {
Map<String, List<String>> result = new HashMap<>();
for (Entry<String, List<String>> entry : map.entrySet()) {
for (value : entry.getValue()) {
List<String> keys;
if (result.containsKey(value)) {
keys = result.get(value);
} else {
keys = new ArrayList<String>();
result.put(value, keys);
}
keys.add(entry.getKey());
}
}
return result;
}
static List<String> keysForValue(String value) {
return valueKeys.get(value);
}
public static void main(String args[]){
public static final Map<String, List<String>> m = new HashMap<>();
checkStringInMapOfLists("gummi",m);
}
private boolean checkStringInMapOfLists(String input,Map<String, List<String>> m){
for(List<String> list : m.values()){
if(list.contains(input))
return true;
}
return false;
}
public static void main(String[] args) {
try {
App app = new App();
String parameter = "invalid value";
int numberOfKeys = 1000000;
Map<String, List<String>> m = new HashMap<>();
// adding values to map
for (int i = 0; i < numberOfKeys ; i++) {
m.put(i + "",
Arrays.asList(i * 10 + "", i * 11 + "", i * 12 + "", i * 13 + "", i * 14 + "", i * 15 + ""));
}
/** check time difference **/
System.out.println("Loops");
long begin = System.nanoTime();
boolean b = app.containsValue_loops(m, parameter);
System.out.println(System.nanoTime() - begin);
System.out.println(b);
System.out.println("\nJava 8 - stream");
begin = System.nanoTime();
boolean a = app.containsValue_java8(m, parameter);
System.out.println(System.nanoTime() - begin);
System.out.println(a);
System.out.println("\nJava 8 - parallel stream");
begin = System.nanoTime();
boolean c = app.containsValue_java8_parallel(m, parameter);
System.out.println(System.nanoTime() - begin);
System.out.println(c);
} catch (Exception e) {
System.out.println(e);
}
}
/** Checks parameter contains in the list using loops **/
public boolean containsValue_loops(Map<String, List<String>> m, String parameter) {
for (List<String> list : m.values()) {
if (list.contains(parameter)) {
// return immediately if value contains in the list
return true;
}
}
return false;
}
/** Checks parameter contains in the list using streams **/
public boolean containsValue_java8(Map<String, List<String>> m, String parameter) {
return m.values().stream().anyMatch(list -> list.contains(parameter));
}
/** Checks parameter contains in the list using parallel streams **/
public boolean containsValue_java8_parallel(Map<String, List<String>> m, String parameter) {
return m.values().parallelStream().anyMatch(list -> list.contains(parameter));
}
Loops
73688600
false
Java 8 - stream
107543400
false
Java 8 - parallel stream
51464500
false
Loops
185000
false
Java 8 - stream
31721800
false
Java 8 - parallel stream
2987000
false
Map<String, List<String>> m = new HashMap<>();
String searchStr="a";
List<String> list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
m.put("1", list1);
list1 = new ArrayList<>();
list1.add("c");
m.put("2", list1);
list1 = new ArrayList<>();
list1.add("a");
list1.add("d");
m.put("3", list1);
for (Entry<String, List<String>> entry : m.entrySet()) {
if (entry.getValue().contains(searchStr)) {
System.out.println(searchStr+" found for map key="+entry.getKey());
}
}
for(String key:m.keyset()){
if(m.get(key).contains("gummi")) return true;
}
return false;
boolean presentInAnyValue = m.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toSet())
.contains("gummi");
Set<String> set = new HashSet<>();
for (List<String> strings : m.values()) {
set.addAll(strings);
}
boolean presentInAnyValue = set.contains("gummi");
public String getKeyForValue(String value) {
for (String key : map.keySet())
if (map.get(key).contains(value))
return key;
return null;
}
public boolean mapContains(String value) {
for (String key : map.keySet())
if (map.get(key).contains(value))
return true;
return false;
}
private static boolean isInListOfHash(Map<List<String>, ICommand> hashMap, String word) {
for (List<String> list : hashMap.keySet()) {
for (String string : list)
if (string.equalsIgnoreCase(word))
return true;
}
return false;
}