You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中Comparator使用问题:Map<String, AtomicInteger>按值排序

How to Sort a Map<String, AtomicInteger> by Its Values in Java

Let's break down the issues with your current approaches and fix them, plus show you a cleaner way to handle this using Java 8+ streams.

Why Your Current Code Isn't Working

  1. Lambda Comparator Issue: When you cast entry to Object, the compiler doesn't recognize it as a Map.Entry—so calling entry.getValue() throws a compile error. You need to explicitly cast it to the correct entry type.
  2. Anonymous Inner Class Issue: Using a raw Comparator (without specifying the generic type) leads to unsafe type casts, and the incomplete code in your snippet (you cut off getValue(...)) likely causes compilation or runtime errors.

Fixed Approach 1: Corrected Lambda with Arrays.sort()

Fix the type casting in your lambda to tell the compiler you're dealing with Map.Entry<String, AtomicInteger>:

Object[] a = map.entrySet().toArray();
// Ascending order (smallest to largest AtomicInteger value)
Arrays.sort(a, Comparator.comparingInt(entry -> 
    ((Map.Entry<String, AtomicInteger>) entry).getValue().get()
));

// For descending order (largest to smallest), add .reversed()
Arrays.sort(a, Comparator.comparingInt((Map.Entry<String, AtomicInteger> entry) -> 
    entry.getValue().get()
).reversed());

Fixed Approach 2: Type-Safe Anonymous Inner Class

Avoid raw types by specifying the generic Comparator<Map.Entry<String, AtomicInteger>>, and use Integer.compare() to prevent integer overflow issues (better than subtracting values directly):

Object[] a = map.entrySet().toArray();
Arrays.sort(a, new Comparator<Map.Entry<String, AtomicInteger>>() {
    @Override
    public int compare(Map.Entry<String, AtomicInteger> o1, Map.Entry<String, AtomicInteger> o2) {
        // Ascending order
        return Integer.compare(o1.getValue().get(), o2.getValue().get());
        // Descending order: return Integer.compare(o2.getValue().get(), o1.getValue().get());
    }
});

Instead of dealing with Object[] arrays, use streams to directly sort and collect the entries into a list—this avoids manual type casts and makes the code more readable:

// Sort entries in ascending order of AtomicInteger value
List<Map.Entry<String, AtomicInteger>> sortedAsc = map.entrySet()
    .stream()
    .sorted(Comparator.comparingInt(entry -> entry.getValue().get()))
    .collect(Collectors.toList());

// Sort in descending order
List<Map.Entry<String, AtomicInteger>> sortedDesc = map.entrySet()
    .stream()
    .sorted(Comparator.comparingInt((Map.Entry<String, AtomicInteger> entry) -> entry.getValue().get())
                      .reversed())
    .collect(Collectors.toList());

// Print the sorted results
for (Map.Entry<String, AtomicInteger> entry : sortedAsc) {
    System.out.printf("%s: %d%n", entry.getKey(), entry.getValue().get());
}

Bonus: Handle Ties with Secondary Sort

If multiple entries have the same AtomicInteger value, you can add a secondary sort on the key to ensure consistent ordering:

List<Map.Entry<String, AtomicInteger>> sortedWithTiebreaker = map.entrySet()
    .stream()
    .sorted(Comparator.comparingInt(entry -> entry.getValue().get())
                      .thenComparing(Map.Entry::getKey)) // Sort by key ascending if values match
    .collect(Collectors.toList());

Important Note for Multi-Threaded Environments

Since AtomicInteger is thread-safe, keep in mind that if other threads modify the values while you're sorting, your results might be inconsistent. If this is a concern, consider locking the map during the sorting process or making a copy of the values before sorting.

内容的提问来源于stack exchange,提问作者Karl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:20:40