14

所以我对 Java 很陌生,因此我正在努力通过练习,将我的一个 Python 程序转换为 Java。

我遇到了一个问题,我试图复制行为,从 python 以下将只返回排序的键(按值),而不是值:

popular_numbers = sorted(number_dict, key = number_dict.get, reverse = True)

在 Java 中,我做了一些研究,但还没有为像我这样的 n00b 或类似方法找到足够简单的样本。我找到了使用 Guava 进行排序的示例,但排序似乎返回了一个按键排序的 HashMap。

除了上述之外,我在 Java 中没有发现的关于 Python 的其他优点之一是能够轻松返回已排序值的子集。在 Python 中,我可以简单地执行以下操作:

print "Top 10 Numbers: %s" % popular_numbers[:10]

在此示例中,number_dict 是键值对的字典,其中键表示数字 1..100,值是数字(键)出现的次数:

for n in numbers:
 if not n == '':
   number_dict[n] += 1

最终结果将是这样的:

前 10 位数字:['27', '11', '5', '8', '16', '25', '1', '24', '32', '20']

澄清一下,在 Java 中我已经成功地创建了一个 HashMap,我已经成功地检查了数字并增加了键值对的值。我现在停留在排序并根据值返回前 10 个数字(键)。

4

9 回答 9

10
  1. 将地图entrySet()放入List.
  2. Collections.sort使用和 a对这个列表进行排序,它根据它们的值对 sComparator进行排序。Entry
  3. 使用 的subList(int, int)方法List检索包含前 10 个元素的新列表。

是的,它会比 Python 更冗长:)

于 2013-06-13T19:13:53.590 回答
3

使用 Java 8+,获取整数列表的前 10 个元素:

list.stream().sorted().limit(10).collect(Collectors.toList());

要获取地图键的前 10 个元素,即整数:

map.keySet().stream().sorted().limit(10).collect(Collectors.toMap(Function.identity(), map::get));
于 2018-01-22T12:12:46.187 回答
0

假设您的地图是这样定义的,并且您想根据进行排序:

HashMap<Integer, Integer> map= new HashMap<Integer, Integer>();
//add values
Collection<Integer> values= map.values();
ArrayList<Integer> list= new ArrayList<Integer>(values);
Collections.sort(list);

现在,打印列表的前 10 个元素。

for (int i=0; i<10; i++) {
    System.out.println(list.get(i));
}

map 中的值实际上没有排序,因为HashMap根本没有排序(它根据键的 hashCode 将值存储在桶中)。此代码仅显示地图中的 10 个最小元素。

编辑排序而不丢失键值对:

//sorted tree map
TreeMap<Integer, Integer> tree= new TreeMap<>();

//iterate over a map
Iteartor<Integer> it= map.keySet().iterator();
while (it.hasNext()) {
    Integer key= it.next();
    tree.put(map.get(key), key);
}

现在您有了TreeMap已排序的树,并且从原始映射中反转了键值对,因此您不会丢失信息。

于 2013-06-13T19:11:43.377 回答
0

HashMaps 在 Java 中没有排序,因此没有一个很好的方法来排序它们,而不是通过所有键进行暴力搜索。尝试使用TreeMaphttp ://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html

于 2013-06-13T19:12:02.937 回答
0

尝试下一个:

public static void main(String[] args) {

    // Map for store the numbers
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();

    // Populate the map ...

    // Sort by the more popular number
    Set<Entry<Integer, Integer>> set = map.entrySet();
    List<Entry<Integer, Integer>> list = new ArrayList<>(set);
    Collections.sort(list, new Comparator<Entry<Integer, Integer>>() {
        @Override
        public int compare(Entry<Integer, Integer> a,
                Entry<Integer, Integer> b) {
            return b.getValue() - a.getValue();
        }
    });


    // Output the top 10 numbers
    for (int i = 0; i < 10 && i < list.size(); i++) {
        System.out.println(list.get(i));
    }

}
于 2013-06-13T19:22:30.633 回答
0

Guava Multiset非常适合您的用例,可以很好地替换您的 HashMap。它是一个统计每个元素出现次数的集合。

Multisets有一个方法copyHighestCountFirst,它返回一个按计数排序的不可变 Multiset。

现在一些代码:

Multiset<Integer> counter = HashMultiset.create();
//add Integers 
ImmutableMultiset<Integer> sortedCount = Multisets.copyHighestCountFirst(counter);
//iterate through sortedCount as needed
于 2013-06-13T20:47:30.727 回答
0

使用SortedMap, 调用values()。文档指出以下内容:

The collection's iterator returns the values in ascending order of the corresponding keys

因此,只要您的比较器编写正确,您就可以遍历第一个n

于 2013-06-13T20:53:12.603 回答
0

为了保留排名顺序并有效地返回顶部计数,远小于地图大小的大小:

map.entrySet().stream()
            .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
            .limit(count)
            .collect(toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (e1, e2) -> e1,
                    LinkedHashMap::new))
于 2021-01-07T01:36:23.850 回答
0
  1. 从密钥集中构建一个列表。

  2. 使用键按值对 HashMap 进行排序,以访问 Collection.sort() 方法中的值。

  3. 返回已排序键集的子列表。

  4. 如果您关心这些值,您可以使用第 3 步中的键并构建值集。

    HashMap<String, Integer> hashMap = new HashMap<String, Integer>(); List list = new ArrayList(hashMap.keySet()); Collections.sort(list, (w1, w2) -> hashMap.get(w2) - hashMap.get(w1)); //按值降序排序;

    返回 list.subList(0, 10);

于 2020-10-06T23:25:28.807 回答