TreeMap自定义比较器

时间:2018-08-24 05:33:53

标签: java comparator treemap

所以我想将TreeMap与自定义比较器一起使用 我的键是一个String:id,我的值是一个int:count; 我需要比较计数,作为树形图中的值(整数) 所以我有:

在一堂课:

import java.util.*;

public TreeMap<String, Integer> tm = new TreeMap<String, Integer>(new SortIdCount<Integer>());

在另一个班级:

import java.util.Comparator;

public class SortIdCount implements Comparator<Integer>{

    public int compare(Integer count1, Integer count2) {
        return count1.compareTo(count2);
    }

}

它在日食中显示错误:

The type SortIdCount is not generic; it cannot be parameterized with arguments <Integer>

5 个答案:

答案 0 :(得分:1)

  

SortIdCount类型不是通用的;不能用   参数<整数>

原因:类SortIdCount不是通用类型的,因此您不能传递 parameterized 参数。 错误提示:(new SortIdCount<Integer>()

  

注意:TreeMap始终根据其键进行排序,但是如果您   想要根据其值对它进行排序,那么您可以构建一个逻辑来执行   使用比较器。下面是对TreeMap进行排序的完整代码   按值。

对值进行排序您可以参考下面的代码片段。

import java.util.*;

public class TreeMapDemo {
  //Method for sorting the TreeMap based on values
  public static <K, V extends Comparable<V>> Map<K, V> 
    sortByValues(final Map<K, V> map) {
    Comparator<K> valueComparator = 
             new Comparator<K>() {
      public int compare(K k1, K k2) {
        int compare = 
              map.get(k1).compareTo(map.get(k2));
        if (compare == 0) 
          return 1;
        else 
          return compare;
      }
    };

    Map<K, V> sortedByValues = 
      new TreeMap<>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
  }
  public static void main(String args[]) {

    TreeMap<String, Integer> treemap = new TreeMap<>();

    // Put elements to the map
    treemap.put("Key1", 5);
    treemap.put("Key2", 4);
    treemap.put("Key3", 3);
    treemap.put("Key4", 2);
    treemap.put("Key5", 1);

    // Calling the method sortByvalues
    Map sortedMap = sortByValues(treemap);

    // Get a set of the entries on the sorted map
    Set set = sortedMap.entrySet();

    // Get an iterator
    Iterator i = set.iterator();

    // Display elements
    while(i.hasNext()) {
      Map.Entry me = (Map.Entry)i.next();
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }
  }
}

有关更多详细信息,请参阅此answer

答案 1 :(得分:1)

正如其他人可能已经提到的,TreeMap constructor中使用的Comparator用于通过对地图进行排序

  

公共TreeMap(比较器比较器)

     

...根据给定的比较器排序。给定的比较器必须将插入到映射中的所有相互比较:compare.compare(k1,k2)不得对映射中的任何键k1和k2抛出ClassCastException ...

但是,如果您想按对地图进行排序,我们仍然可以使用LinkedHashMap作为解决方案:

    Map<String, Integer> treeMap = new TreeMap<>();
    treeMap.put("hi", 1);
    treeMap.put("there", 3);
    treeMap.put("hey", 2);
    treeMap = treeMap.entrySet().stream().sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldV, newV) -> oldV, LinkedHashMap::new));
    System.out.println(treeMap);

输出:

{there=3, hey=2, hi=1}

答案 2 :(得分:0)

您不能使用TreeMap来按值排序。有很多方法可以按值对地图进行排序,但是我相信TreeMap并不适合这种方式。如果您查看TreeMap构造函数:TreeMap(Comparator<? super K> comparator),它将比较器作为参数,则它的通用类型显然应该是super of Key of the Map。因此,当密钥为Comparator<Integer>时无法发送String

请遵循answer以按值对地图进行排序。

答案 3 :(得分:0)

用于TreeMap的比较器必须比较键,而不是值。

因此,比较将必须采用传递的键并在映射中查找值。那里有经典的母鸡(地图)和鸡蛋(比较器)问题。您需要比较器来创建映射,但是由于比较器必须查看映射,因此需要比较器的映射。您可以通过在创建地图后使用comparator.setMap(map)来解决此问题。

但是最关键的问题是,您的地图无法使用。只要条目未写入映射,就没有该值,因此比较器将无法工作。我对此的唯一想法是使用两个地图。既字符串,整数。第一个仅用于比较器中的查找。因此,您始终必须先放入第一个,然后再放入第二个。

然后您仍然遇到问题,因为您可能很容易违反SortedMap合同。将键插入地图后,不得更改(关于排序)。但是,只要您输入另一个值,就可以对键进行不同的排序。

因此,我真的会重新考虑您的要求以及TreeMap是否是满足您需求的最佳解决方案。

答案 4 :(得分:-1)

public class SortIdCount implements Comparator<String> {

    public int compare(String count1, String count2) {
        return count1.compareTo(count2);
    }
}