从哈希图中的所有集合中获取公共值的最快方法是什么?
我有一个
Map<String, Set<String>>
我检查密钥并获取所有具有给定密钥的集合。但是,除了从 hashmap 中获取所有集合之外,还有没有更好的方法来从所有集合中获取公共元素(值)?
例如,哈希图包含,
abc:[ax1,au2,au3]
def:[ax1,aj5]
ijk:[ax1,au2]
我想单独提取ax1
and au2
,因为它们是集合中最常见的值。
注意:不确定这是否是最快的,但这是一种方法。
首先,编写一个简单的方法来提取映射中所有值集出现的字符串的频率。这是一个简单的实现:
Map<String, Integer> getFrequencies(Map<String, Set<String>> map) {
Map<String, Integer> frequencies = new HashMap<String, Integer>();
for(String key : map.keySet()) {
for(String element : map.get(key)) {
int count;
if(frequencies.containsKey(element)) {
count = frequencies.get(element);
} else {
count = 1;
}
frequencies.put(element, count + 1);
}
}
return new frequencies;
}
您可以像这样简单地调用此方法:Map<String, Integer> frequencies = getFrequencies(map)
其次,为了获得地图中最“常见”的元素,您只需使用Comparator 接口frequencies
对地图中的条目进行排序。碰巧 SO 有一个优秀的社区 wiki 讨论了这个问题:Sort a Map<Key, Value> by values (Java)。wiki 包含多个有趣的问题解决方案。回顾它们可能会有所帮助。
您可以简单地实现一个类,调用它FrequencyMap
,如下所示。
让类实现Comparator<String>
接口,从而实现int compare(String a, String b)
使地图元素按值整数的升序排序的方法。
第三,实现另一个方法,调用它getCommon(int threshold)
并传递一个阈值。地图中频率值大于 的任何条目threshold
都可以视为“常见”,并将作为简单列表返回。
class FrequencyMap implements Comparator<String> {
Map<String, Integer> map;
public FrequencyMap(Map<String, Integer> map) {
this.map = map;
}
public int compare(String a, String b) {
if (map.get(a) >= map.get(b)) {
return -1;
} else {
return 1;
} // returning 0 would merge keys
}
public ArrayList<String> getCommon(int threshold) {
ArrayList<String> common = new ArrayList<String>();
for(String key : this.map.keySet()) {
if(this.map.get(key) >= threshold) {
common.add(key);
}
}
return common;
}
@Override public String toString() {
return this.map.toString();
}
}
所以使用 FrequencyMap 类和getCommon
方法,它归结为这几行代码:
FrequencyMap frequencyMap = new FrequencyMap(frequencies);
System.out.println(frequencyMap.getCommon(2));
System.out.println(frequencyMap.getCommon(3));
System.out.println(frequencyMap.getCommon(4));
对于您问题中的示例输入,这是您得到的 o/p:
// common values
[ax1, au6, au3, au2]
[ax1, au2]
[ax1]
此外,这是一个包含我为这个问题准备的代码的要点:https ://gist.github.com/VijayKrishna/5973268