如何生成散列图的N个排序键列表,按值排序?

时间:2013-11-08 01:54:46

标签: c# java sorting hashmap

我对Java不是很熟悉,而且我不太清楚如何将这个从c#转换为java。

Dictionary<string, int> myDictionary = GetDictionary();
int N = 10;

myDictionary
         .OrderByDescending(dictionaryEntry => dictionaryEntry.Value)
         .Take(N)
         .Select(dictionaryEntry => dictionaryEntry.Key)
         .ToList();

现在,我知道字典本身并没有被排序,它只是一个新的IEnumberable,这没关系。

谢谢!

3 个答案:

答案 0 :(得分:1)

我不是C#家伙,我从来没有使用过它,但如果我猜一下,你好像是按照降序排列地图,检索10个第一个元素,然后转换将这10个元素的键放入列表中。

如果已知这些值是不同的,那么它就是微不足道的 - 您只需转换为带有键和值的SortedMap。所以我假设这些值并不明显,即相同的数字可能会出现多次。

在这种情况下,它并不是那么简单,绝对不像在C#示例中那么简单。我的第一个想法是创建一个带有自定义比较器的有序集,其中集合中的每个元素都是来自地图的Map.Entry,其中交换了键和值。

这实际上需要Java中的相当多的代码。这是一次尝试:

// Create a SortedSet of the reversed entry set, with a custom comparator for sorting
SortedSet<Map.Entry<Integer, String>> sortedSet = new TreeSet<Map.Entry<Integer, String>>(
        new Comparator<Map.Entry<Integer, String>>() {
    public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
        // sort by key, then by value --> in descending order
        int keyCompareResult = -o1.getKey().compareTo(o2.getKey()); // negate --> descending
        int valueCompareResult = o1.getValue().compareTo(o2.getValue());
        return keyCompareResult == 0 ? valueCompareResult : -keyCompareResult;
    }
});

// Add all entries of the map to the sorted set
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    Map.Entry<Integer, String> reversedEntry = new AbstractMap.SimpleEntry<Integer, String>(entry.getValue(), entry.getKey());
    sortedSet.add(reversedEntry);
}

// Convert the 10 first elements to the resulting list
int N = 10;
List<String> result = new ArrayList<String>(N);
Iterator<Map.Entry<Integer,String>> iterator = sortedSet.iterator();
while (iterator.hasNext() && result.size() < N) {
    Map.Entry<Integer, String> entry = iterator.next();
    result.add(entry.getValue());
}

答案 1 :(得分:0)

我想出了与Steinar建议的相同的东西,如果你知道更多的LINQ-y /功能方式,请添加你的答案!

//Convert to List of Map.Entry
ArrayList<Map.Entry<String,Integer>> myArrayList = ArrayList<Map.Entry<String,Integer>>(myHashMap.entrySet());

//Natural order is ascending, so we reverse the comparator to get it Descending.
Collections.sort(myArrayList , Collections.reverseOrder(new EntryComparator()));

//Create list and add Keys

List<String> topNStrings =  new ArrayList<String>();

for (int i = 0; i < N && i < myArrayList.size(); i++)
{
  topNStrings.add(myArrayList.get(i).getKey());
}

并有一个单独的小比较类

private class EntryComparator implements Comparator<Map.Entry<String,Integer>>
    {
    @Override
    public int compare(Map.Entry<String,Integer> x, Map.Entry<String,Integer> y)
    {
        return compare(x.getValue(), y.getValue());
    }

    private int compare(Integer a, Integer b)
    {
        return a < b ? -1
                : a > b ? 1
                : 0;
    }
}

答案 2 :(得分:-1)

让我们从HashMap<String, Integer> map以某种方式定义的任意HashMap开始。

我们要对进行排序,然后获取第一个N值。

int N = 10;

List<Integer> values = new ArrayList<Integer>( map.values() );
Collections.sort(values);
List<Integer> N_values = values.subList(0, N);