Java 为什么我';在向TreeSet添加元素时,我没有得到类强制转换异常或其他一些东西
下面是我的代码Java 为什么我';在向TreeSet添加元素时,我没有得到类强制转换异常或其他一些东西,java,collections,Java,Collections,下面是我的代码 class NumberComparator<Number> implements Comparator<Number> { public int compare(Number o1, Number o2) { return 1; } } public class Ex28 { public static void main(String[] args) { TreeSet set = new Tr
class NumberComparator<Number> implements Comparator<Number> {
public int compare(Number o1, Number o2) {
return 1;
}
}
public class Ex28 {
public static void main(String[] args) {
TreeSet set = new TreeSet(new NumberComparator<Number>());
set.add(1);
set.add(1.4f);
set.add(1L);
set.add("1a");
System.out.println(set);
}
}
任何人都可以解释为什么会发生这种情况。树集的
比较器用于排序,而不是抛出CCE。由于您的比较器设计为对所有内容返回1
,这意味着排序不正确
这就是您的输出未排序的原因
请务必阅读TreeSet
构造函数的文档
/**
* Constructs a new, empty tree set, sorted according to the specified
* comparator. All elements inserted into the set must be <i>mutually
* comparable</i> by the specified comparator: {@code comparator.compare(e1,
* e2)} must not throw a {@code ClassCastException} for any elements
* {@code e1} and {@code e2} in the set. If the user attempts to add
* an element to the set that violates this constraint, the
* {@code add} call will throw a {@code ClassCastException}.
*
* @param comparator the comparator that will be used to order this set.
* If {@code null}, the {@linkplain Comparable natural
* ordering} of the elements will be used.
*/
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
问题是一些不良做法的混合:
- 您正在为
TreeSet
- 您的
NumberComparator
是泛型(Number
是一个类型参数)
这里的Number
是一个类型参数,这意味着类型擦除意味着您实际上不会转换为真正的Number
类型
如果将比较器更改为:
class NumberComparator implements Comparator<Number> {
public int compare(Number o1, Number o2) {
return 1;
}
}
那我就期待一个例外
此外,如果您将代码更改为不使用原始类型:
TreeSet<Number> set = new TreeSet<Number>(new NumberComparator());
TreeSet set=newtreeset(newnumbercomparator());
然后您将得到一个编译时错误。总之,如果您将比较器定义为如下所示,您将得到类强制转换异常:)
import java.util.Comparator;
类NumberComparator实现了Comparator{
公共int比较(java.lang.Number o1,java.lang.Number o2){
返回1;
}
}
谢谢,我理解,这意味着数字是类型(实际上不是java.lang.Number),所以在运行时它变成了java.lang.Object,所以没有类强制转换异常。但为什么它变成了类型呢?。还有一件事我无法理解。@KrushnaCh.Dash:你说的“但为什么它会成为类型”是什么意思?您在NumberComparator中将其声明为类型参数。哦,对不起,我犯了错误,我知道comparator实现也很糟糕,我相信如果它实际使用了这些数字(比如,intValue
),您可能会因此而得到一个异常。更好的是,然后:如果你一直在编写一个真正的比较器而不是一个伪造的比较器,你会因为试图对这个数字做任何事情而得到一个编译错误。只是出于好奇,你在这里的实际目标是什么?总是返回1的比较器是非常错误的。在这个更改之后,将类参数化是没有意义的,所以将它重命名为NumberComparator
,而不是NumberComparator
。
class NumberComparator implements Comparator<Number> {
public int compare(Number o1, Number o2) {
return 1;
}
}
TreeSet set = new TreeSet(new NumberComparator());
TreeSet<Number> set = new TreeSet<Number>(new NumberComparator());
import java.util.Comparator;
class NumberComparator<Number> implements Comparator<java.lang.Number> {
public int compare(java.lang.Number o1, java.lang.Number o2) {
return 1;
}
}