Collections.sort(List<T>, Comparator<? super T>) 抛出 ClassCastException 的可能原因是什么?

4
我正在使用先前声明的比较器,在一个ArrayList上调用Collections.sort()方法。
ArrayList<Employee> list = new ArrayList<Employee>();
Comparator<Employee> comparator = new Comparator<Employee>() {

  public int compare(Employee o1, Employee o2) {
    return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
  }

};

...

Collections.sort(list, comparator);

出现这种情况的原因可能是,sort方法默认将集合元素转换为Comparable类型进行比较,而忽略了已经传入的Comparator。您可以检查一下是否正确地向sort方法传递了Comparator。
以下是堆栈跟踪信息,供参考:
Exception in thread "Thread-3" java.lang.ClassCastException: processing.app.EmployeeManager$PrettyOkayEmpolyee cannot be cast to java.lang.Comparable
    at java.util.Arrays.mergeSort(Unknown Source)
    at java.util.Arrays.sort(Unknown Source)
    at java.util.Collections.sort(Unknown Source)
    at foobar.Main.doSomeSorting(Main.java:140)
    ...
    at java.lang.Thread.run(Unknown Source)

没有看到代码,很难告诉你出了什么问题。请发布“Flub”和比较器的定义。 - Jim Garrison
1个回答

9
您传递的Comparator对象可能为null
Javadoc中指出:
@param c用于确定列表顺序的比较器。如果值为null,则表示应使用元素的自然排序。
因此,如果Comparatornull,它将假定参数是可比较的。在Arrays.sort中的代码与此一致。我认为如果Comparatornull,它确实应该抛出NPE,但它是方法合同的一部分,因此无法更改。

1
...就是这样!我本来以为会出现NullPointerException。我真傻。 - peskal
@ColinD 谢谢你。我花了一个小时跟踪我的代码,确认我确实向我使用的TreeSet提供了一个Comparator,只有你在这里的答案让我检查它实际上不是null。我愚蠢地在静态单例类实例之后声明了一个静态比较器。因此,在构建TreeSet时,单例将看到Comparator的空值。 - Bobulous

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接