混淆HashMap的方法containsValue

时间:2011-06-28 06:38:47

标签: java arrays string loops hashmap

我正在尝试找到我的方法的简化版本,我想知道你是否有更好的意见。

基本上我有一个HashMap,它将键值存储为String-String []

我希望有一个方法可以找出一个新插入的String [] - 值,是否包含已存在于已存储的String [] - 值中的String。

我写的“显然工作正常”是以下方法:

static Map<String,String[]> myMap=new HashMap<String,String[]>();

    public static boolean kijkContains(String[] syn){

for(String s:myMap.keySet()){

    String[]temp=myMap.get(s);

    for(int i=0; i<temp.length; i++){

        for(int k=0; k<syn.length; k++){

            if(temp[i].equals(syn[k])){

                return true;
            }
        }
    }
  }
return false;
}

我怀疑是循环次数,这显然是一种耗费大量内存的方法,我想知道你是否能想到更好的版本。

我尝试使用Map的containsValue()方法,但由于该方法将String []视为值,而不是通过数组读取,因此我无法将其用作比较器。

6 个答案:

答案 0 :(得分:3)

使用您目前拥有的数据结构,没有比循环所有这些值更好的方法了(至少你在第一次点击的时候早点爆发)。

如果性能确实成为一个问题,您可能希望保留第二个数据结构来索引已存在的内容。如果您只需要知道给定的字符串是否(在地图中(深处)),那么HashSet<String>可能会起作用。

这是内存权衡:增加的索引结构会占用额外的空间。 (顺便说一下,你现在正在做的事情除了地图已经占用之外不会使用任何空间,你只是通过引用迭代数组,没有额外的副本)。

答案 1 :(得分:2)

您的代码没有使用特别大的内存,因为您没有创建任何String[]的副本(您只是复制对它们的引用,这非常便宜)。

然而,你需要遍历HashMap中的所有值,这使得这个O(n)(或简单地说:慢)。

如果这是一个相对罕见的操作,那么这可能是可以接受的,我不担心。

如果插入是一种常见的操作,那么你一定要考虑更好的数据结构(你需要告诉我们更多关于实际用例的信息,以便我们在这里提出好的建议)。

答案 2 :(得分:0)

嗯我不知道循环使用这些值的另一种方法,但我会建议更简单的代码:

Map<String, String[]> map = new HashMap<String, String[]>();
for (String[] strings : map.values()) {
    ArrayUtils.contains(strings, "foo");
}

ArrayUtils是来自apache commons的帮助器类,当然你也可以通过字符串数组循环并每次调用equals。请注意这是区分大小写的。

Map<String, String[]> map = new HashMap<String, String[]>();
for (String[] strings : map.values()) {
    for (String string : strings) {
        if (string.equals("foo")) {
            return true;
        }
    }
}

答案 3 :(得分:0)

通过将syn数组复制到HashSet中,可以减少时间复杂度。然后,不是一遍又一遍地遍历syn,而是可以使用HashSet#contains方法,即O(1):

public static boolean kijkContains(String[] syn){
  if (syn == null || syn.length == 0) return false; // that was missing
  Set<String> input = new HashSet<String>();
  for (String s:syn)
    input.add(s);         // will remove duplicates, another perfo improvement

  for(String key:myMap.keySet()){
    for(String s:myMap.get(key)){  // we don't need the loop variable
      if (input.contains(s)) {
        return true;
      }
    }
  }
  return false;
}

复杂性 O(i*j*k)我已将其缩小为O(i*j+k)(i为地图的大小,j为平均值值数组的大小和k的syn数组的大小)

答案 4 :(得分:0)

所以你想要的是HashMap值中的每个字符串必须是唯一的。 我认为如果你使用HashSet而不是String []作为Map的值,它将起作用。

import java.util。*;

公共类TestHashMap {   public static void main(String args []){

System.out.println("Hashmap Test");
HashMap<String, HashSet> myMap = new HashMap<String, HashSet>();

HashSet<String> s1 = new HashSet<String>();
s1.add("one");
s1.add("two");
s1.add("three");

myMap.put("1", s1);
System.out.println("Value for key 1" + myMap.get("1"));

} }

我希望这是你想要的方式。

答案 5 :(得分:-1)