是什么导致ClassCastException:java.util.TreeSet无法强制转换为java.lang.Comparable?

时间:2014-02-06 01:51:20

标签: java collections treemap

所以我试图将一串长度的所有字符串从一个字符串集合(可以是一个集合或一个列表)移动到一个TreeMap,并将每个字符串中的一组字符设置为该字符串的键 但是map.put(keyRinger(word), word);行会引发java.lang.ClassCastException: java.util.TreeSet cannot be cast to java.lang.Comparable

Map<Set<Character>, String> map = new TreeMap<Set<Character>, String>();
for (String words : words)    {
  if (word.length() == length)  {
    map.put(keyRinger(word), word);
  }
}

如果您感到好奇,这是keyRing方法。

private Set<Character> keyRinger(String current)  { 
  Set<Character> keyRing = new TreeSet<Character>();
  for (int i = 0; i < current.length(); i++)   {
    char key = current.charAt(i); 
    keyRing.add(key);
  }
  return keyRing;
}

所以我的问题是我该怎么办才能避免这种情况?我已经读过我需要一个Comparator或者实现Comparable但是我不知道如何做到这一点,我认为可能有一个更简单的解决方案(尽管可能效率不高)。

2 个答案:

答案 0 :(得分:3)

你会注意到TreeMap个州的javadoc

  

地图根据其键的自然顺序排序,或者按照   比较器在地图创建时提供,具体取决于哪个   使用构造函数。

因此,如果您不提供Comparator,则会使用自然排序。什么是自然排序? Comparable接口的javadoc状态

  

此接口对每个类的对象施加总排序   实现它。 此排序称为类   自然排序,和类的compareTo方法被称为   它的自然比较方法。

因此,TreeMap中的关键元素必须实现Comparable。您正尝试将TreeSet个实例用作TreeMap中的关键字。 TreeSet未实施Comparable

ClassCastException尝试将密钥转换为TreeMap引用以便使用其Comparable方法时,您会得到compareTo

要解决此问题,您应该通过提供自己的自定义TreeMap来创建Comparator,以便比较Set<Character>个实例。

答案 1 :(得分:0)

以下是创建比较器类的方法:

public class NutrientByInclusionOrderComparator  implements Comparator<ProductNutrient>{

@Override
public int compare(ProductNutrient o1, ProductNutrient o2) {
    if (o1 == null && o2 == null){
        return 0;
    }
    else if (o1 == null){
        return -1;
    }
    else if (o2 == null){
        return 1;
    }
    else if ( o1.getNumOrder().compareTo(o2.getNumOrder()) == 0) {
        return o1.getDtInclusion().compareTo(o2.getDtInclusion());
    } else {
        return o1.getNumOrder().compareTo(o2.getNumOrder());
    }
}

}

然后,在创建TreeSet时:

Set<ProductNutrient> productNutrients = new TreeSet<ProductNutrient>(new NutrientByInclusionOrderComparator());

干杯!