【问题标题】:Java : How to sort values of a HashMap with generic Key and Value?Java:如何使用通用键和值对 HashMap 的值进行排序?
【发布时间】:2014-07-11 08:57:32
【问题描述】:

我有一个需要按值排序的 TreeMap。如果值是整数类型,我可以对地图进行排序。

public class MapSorting {

    public static Map<String, Integer> sortByValues(Map<String, Integer> tempMap) {

        ValueComparator bvc = new ValueComparator(tempMap);
        Map<String, Integer> sortedMap = new TreeMap<String, Integer>(bvc);
        sortedMap.putAll(tempMap);
        return sortedMap;

    }
}


class ValueComparator implements Comparator<String> {

        Map<String, Integer> base;

        public ValueComparator(Map<String, Integer> base) {
            this.base = base;
        }

        public int compare(String a, String b) {
            if (base.get(a) >= base.get(b)) {
                return -1;
            } else {
                return 1;
            }
        }
    }

但是我如何使方法通用?我希望能够将带有任何类型的键和值的 Map 发送到此方法。

我想返回一个基于值排序的 TreeMap。

有人可以帮忙吗?

【问题讨论】:

  • 您可以使用 instanceOfgetClass() 来获取对象的类型并在您的 compare(Object, Object) 方法中进行不同的比较。但是您为什么要这样做呢? Generics 的引入是为了防止此类使用引起的错误。如果您正在考虑打破泛型,我相信您的设计存在缺陷。
  • 您必须将compare 设为通用。但是为什么要使 key 和 value 通用?用例是什么?
  • TreeMap 旨在按键排序,但您希望按值对其进行排序。我认为 TreeMap 不适合您的需要。例如,您可以将TreeMap&lt;String, Integer&gt; 转换为List&lt;Entry&lt;Integer, String&gt;&gt;,这样排序会容易得多。
  • @TheLostMind 我想让方法 sortByValues 通用,以便可以为任何类型的地图对象调用它,即 Map 或 Map 或 Map.
  • @ArnaudDenoyelle 如果地图值是整数,则代码工作正常。如果 Map Values 也是 String 类型,我需要帮助才能使该方法正常工作。因此,我需要一种适用于所有类型的键和值的通用方法。

标签: java generics comparator comparable


【解决方案1】:

注意TreeMap 旨在按键排序,而不是按值排序。这让我认为你应该使用另一个数据结构来存储你的结果:例如List&lt;Entry&lt;K, V&gt;&gt;.

注意:我强烈反对使用这段代码,因为我认为它是一种反模式。我这样做只是为了展示它是如何可能的。

也就是说,我是这样设计的(至少需要 Java 8 或修改代码):

public static <K, V extends Comparable> Map<K, V> sortByValues(Map<K, V> tempMap) {
  TreeMap<K, V> map = new TreeMap<>(buildComparator(tempMap));
  map.putAll(tempMap);
  return map;
}

public static <K, V extends Comparable> Comparator<? super K> buildComparator(final Map<K, V> tempMap) {
  return (o1, o2) -> tempMap.get(o1).compareTo(tempMap.get(o2));
}

测试:

Map<Integer, String> map = new HashMap<>();
map.put(1, "B");
map.put(2, "C");
map.put(3, "A");

for(Map.Entry<Integer, String> entry : sortByValues(map).entrySet()) {
  System.out.println(entry.getKey()+" : "+ entry.getValue());
}

输出:

3 : A
1 : B
2 : C

注意:我不处理 null 案例,因为这对于这个解释并不重要。

【讨论】:

    【解决方案2】:

    您可以创建一个比较器来比较 Comparable 的值:

    class ValueComparator<Comparable> implements Comparator<Comparable> {
    
        Map<String, Comparable> base;
    
        public ValueComparator(Map<String, Comparable> base) {
            this.base = base;
        }
    
        public int compare(Comparable a, Comparable b) {
            return a.compareTo(b);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-07-19
      • 2013-11-03
      • 2015-10-01
      • 2014-12-11
      • 2014-11-18
      • 2011-11-05
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多