关于 HashMap 方法 containsValue 的困惑
我正在尝试找到我的方法的简化版本,我想知道您是否有更好的意见。
基本上我有一个将键值存储为 String-String[] 的 HashMap
我想要一种方法来查找新插入的 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[] 视为值而不是读取数组,因此我无法真正将其用作比较器。
I'm trying to find a simplified version of my method and I wanted to know if you have a better opinion.
Basically I have a HashMap that stores key-value as String-String[]
I would like to have a method that finds out if a new inserted String[]-value, contains a String that is already present in already stored String[]-value.
What I have written "and apparently works fine" is the following method:
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;
}
My doubts are about the number of loops, it is obviously a high memory-consuming method, and I was wondering if you can think of any better version.
I have tried with Map's containsValue() method but since that method sees as value the String[] instead of reading through the array, I cant really use it as comparator.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
对于您当前拥有的数据结构,没有比循环所有这些值更好的方法了(至少您在第一次点击时就提前突破了)。
如果性能确实成为一个问题,您可能需要保留第二个数据结构来索引已有的数据结构。如果您只需要知道给定的字符串是否在映射中(而不是位置)(而不是位置),那么
HashSet
可能会起作用。这是一个内存权衡:添加的索引结构将占用额外的空间。 (顺便说一句,除了地图已经占用的空间之外,您现在所做的不使用任何空间,您只是通过引用迭代数组,没有创建额外的副本)。
With the data structure you currently have, there is no better way than looping over all those values (at least you are breaking out early on the first hit).
If performance does become a concern, you may want to keep a second datastructure to index what is already there. If you only need to know if a given String is (deep) in the Map (but not where), maybe a
HashSet<String>
would work.This is a memory tradeoff: The added index structure would take up extra space. (By the way, what you are doing now does not use any space in addition to what the map already takes up, you are just iterating over arrays by reference, there are no extra copies being made).
您的代码不会使用特别大量的内存,因为您没有创建任何
String[]
的副本(您只是复制对它们的引用,这非常便宜)。但是,您需要循环遍历
HashMap
中的所有值,这使得这个O(n)(或者简单地说:慢)。如果这是一个相对罕见的操作,那么这可能是可以接受的,我不会担心。
如果插入是一种常见操作,那么您绝对应该为此考虑更好的数据结构(您需要告诉我们更多有关实际用例的信息,以便我们在这里提出好的建议)。
Your code doesn't use a particularly big amount of memory, since you're not creating copies of any
String[]
(you're only copying references to them, which is very cheap).However, you need to loop through all values in the
HashMap
, which makes this O(n) (or simply speaking: slow).If this is a relatively rare operation, then this is probably acceptable, and I wouldn't worry about it.
If inserting is a common operation, then you should definitely think about a better data structure for this (you'd need to tell us more about the actual use case for us to make good suggestions here).
好吧,除了循环遍历值之外,我不知道还有什么不同的方法,但我建议使用更简单的代码:
ArrayUtils 是来自 apache commons 的辅助类,但当然您也可以循环遍历字符串数组并调用 equalseach时间。请注意,这是区分大小写的。
Well I didn't know of a different way beside looping trough the values, but I would suggest a more easier code for that:
ArrayUtils is a helper class from apache commons but of course you can also loop trough the strings array and call equals each time. Be carefull that this is case sensitive.
您可以通过将
syn
数组复制到 HashSet 来降低时间复杂度。然后,您可以使用HashSet#contains
方法,而不是一遍又一遍地迭代syn
,该方法的复杂度为 O(1):复杂度为 < code>O(i*j*k) 并且我将其减少为
O(i*j+k)
(其中 i 是地图的大小,j 是 值数组的平均大小和 k syn 数组的大小)You can reduce time complexity by copying the
syn
array into a HashSet. Then instead of iterating oversyn
over and over again you can use theHashSet#contains
method which is O(1):the complexity was
O(i*j*k)
and I've reduced it toO(i*j+k)
(with i being the size of the map, j the average size of the value arrays and k the size of the syn array)所以你想要的是HashMap中的每个字符串的值必须是唯一的。
我认为如果你使用 HashSet 而不是 String[] 作为 Map 的值,它会起作用。
导入 java.util.*;
公共类 TestHashMap {
公共静态无效主(字符串参数[]){
}
我希望
这是您想要的方式。
So what you want is each string in the value of HashMap must be unique.
I think if you use HashSet instead of String[] for the value of Map it will work.
import java.util.*;
public class TestHashMap {
public static void main(String args[]) {
}
}
I hope this is the way you wanted it.
您可以使用 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
you can use containsValue() method to do this.you don't have to iterate throw entire 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