我正在尝试找到我的方法的简化版本,我想知道你是否有更好的意见。
基本上我有一个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 []视为值,而不是通过数组读取,因此我无法将其用作比较器。
答案 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)
您可以使用containsValue()方法执行此操作。您不必迭代抛出整个HashMap。
http://msdn.microsoft.com/en-us/library/aa989118%28v=vs.80%29.aspx
http://www.javadocexamples.com/java/util/HashMap/containsValue%28Object%20value%29.html