从java中的set的hashmap中查找最常见的值?

时间:2013-07-11 02:17:08

标签: java hashmap hashset

从哈希映射中的所有集合中获取公共值的最快方法是什么?

我有一个

Map<String, Set<String>>

我检查并获取具有给定密钥的所有集合。但是没有从hashmap获取所有集合,是否有更好的方法从所有集合中获取公共元素(值)?

例如,hashmap包含

abc:[ax1,au2,au3]
def:[ax1,aj5]
ijk:[ax1,au2]

我想单独提取ax1au2,因为它们是套装中最常见的值。

1 个答案:

答案 0 :(得分:3)

注意:不确定这是否是最快的,但这是一种方法。

首先,编写一个简单的方法来提取地图中所有值集中出现的字符串的频率。这是一个简单的实现:

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)

第二次,为了获得frequencies地图中最“常见”的元素,您只需使用Comparator interface对地图中的条目进行排序即可。事实上,SO有一个很好的社区维基,只讨论:Sort a Map<Key, Value> by values (Java)。维基包含多个有趣的解决方案。它可能有助于克服它们。

您可以简单地实现一个类,将其命名为FrequencyMap,如下所示。

让类实现Comparator<String>接口,从而实现int compare(String a, String b)方法,使地图元素按值Integers的递增顺序排序。

第三次,实现另一种方法,将其称为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