我有一个hashmap<CustomObject,Integer>
,我想比较每个条目中的整数(值)。所以,基本上我想按照Integer
值按降序排序我的值。我有一个Comparator
,其中包含以下内容......
class Compare implements Comparator<Integer>{
Map<CustomObject,Integer> map;
/**
* Constructs our map
* @param map map to be sorted.
*/
public Compare(Map<CustomObject,Integer> map){
this.map = map;
}
/**
* Performs the comparison between two entries.
*/
public int compare(Integer one, Integer two){
if(map.get(one) <= map.get(two)){
return 1;
}else{
return 0;
}
}
}
我通过调用以下代码行将Hashmap
传递给TreeMap .. Tmap.putAll(Hmap);
。其中Tmap和Hmap定义为:
private HashMap<CustomObject,Integer> Hmap;
private TreeMap<CustomObject,Integer> Tmap;
当我运行我的代码时,我收到错误Exception in thread "main" java.lang.ClassCastException: CustomObject cannot be cast to java.lang.Comparable
。
当我尝试从排序列表中提取值时,似乎会调用异常。像这样...
TreeMap<CustomObject,Integer> sorted = Tmap.putAll(hmap);
sorted.get(o);
其中o
是CustomObject。
我想我误解了比较器是如何工作的......我做错了什么?我如何比较两个整数值?
修改
只是为了澄清我实际上要做的事情......
我想比较链接到CustomObject的整数。我无法将关键字作为整数,因为这些整数可能不是唯一的。我要对它们进行比较,因为我想根据它们的Integer值按降序对我的集合进行排序。
答案 0 :(得分:5)
您需要更改比较器以比较CustomObject
,而不是Integers
:
class Compare implements Comparator<CustomObject>{
Map<CustomObject,Integer> map;
/**
* Constructs our map
* @param map map to be sorted.
*/
public Compare(Map<CustomObject,Integer> map){
this.map = map;
}
/**
* Performs the comparison between two entries.
*/
public int compare(CustomObject left, CustomObject right){
return map.get(left).compareTo(map.get(right));
}
}
然后,你需要告诉TreeMap
使用你的比较器:
private Map<CustomObject,Integer> Tmap =
new TreeMap<CustomObject,Integer>(new Compare(HMap));
答案 1 :(得分:1)
new TreeMap<..>(new Compare<..>(map))
构建树时必须指定比较器。否则,它假定您的密钥是可比较的(并且它们不是)
但check this answer用于根据值对地图进行排序。
答案 2 :(得分:1)
这种方法存在一些问题。
compareTo
中使用的字段无法更改或损坏集合。您最好从List<Entry<CustomObject,Integer>>
创建一个map.entrySet()
,您可以对其进行排序,因为这样可以复制并订购。
答案 3 :(得分:1)
我认为问题在于你使用了错误的TreeMap
构造函数。您正在使用的那个键要求所有键都是实现Comparable
的类的实例。您的CustomObject
没有。您应该使用带有Comparator
参数的构造函数; e.g。
TreeMap<CustomObject,Integer> tmap =
new TreeMap<CustomObject,Integer>(new Compare());
这也会告诉您,您的Compare类需要实现Comparator<CustomObject>
而不是Comparator<Integer>
。
另一个问题是你的比较器没有实现正确的语义。如果arg1&lt;比较方法应该返回-ve数字。 arg2,如果arg1 = arg2则为零,如果arg1> gt,则为+ ve编号; ARG2; e.g。
public int compare(CustomObject one, CustomObject two){
return Integer.compare(map.get(one), map.get(two));
}
即使这是狡猾的:
如果映射到同一整数的任何两个CustomObject
实例将被视为相等,则您将无法在TreeMap中同时拥有两个(不同)键。
如果map
或one
two
中没有条目,您的比较器将抛出NPE。
答案 4 :(得分:1)
我建议使用整数索引的多图。如果您需要保留按对象查找这些对的功能,则可以维护两个映射。 Java没有附带多图,但有简单的解决方案。 Here是Map<Integer,List<Object>>
的示例(向下滚动到多地图部分)。
答案 5 :(得分:0)
首先,密钥应该是Integer,值应该是CustomObject,然后可以根据比较器对HashMap进行排序。但是默认情况下,HashMap或者如果你想对CustomObject进行排序,那么你必须使CustomObject实现Comparable并在其中编写compare方法,这将使HashMap基于CustomObject进行排序。如果你已经理解了这一点。并想尝试自己的尝试。或者如果你想让我用一个例子来解释我可以做到。
问题很混乱。