java - java比较器是类型感知的吗?
问题描述
我想要一种基于任何给定 Comparable 类创建 Comparator 对象的简单方法,因此我编写了 ComparatorCreator 对象,我相信它会查看其泛型的类型并返回我可以用来比较对象的正确 Comparator 对象类型。所以我写了下面的代码来测试我的想法。我的信念是,由于 BackwardsInt 类的 compareto 方法是一个反向比较器,它应该能够以相反的顺序比较任何两个数字。但是在执行语句时,它在比较两个整数时完全忽略了反转,甚至抛出了错误。我想知道为什么会这样。我创建的比较器似乎知道我在其参数中传递的数字的类型。
(不久前我也很喜欢有界通配符,所以如果这导致了问题,那么糟糕)。
import java.util.Comparator;
public class what {
public static void main(String[] ignoreme)
{
Comparator comp = new ComparatorCreator<BackwardsInt>().getComparator();
//comp should represent a Comparator<Number> which redirects to BackwardsInt.compareTo
int big=6;
int small=2;
BackwardsInt bbig=new BackwardsInt(6);
BackwardsInt bsmall=new BackwardsInt(2);
System.out.println(comp.compare(bbig, bsmall));//prints -1 good
System.out.println(comp.compare(bbig, small));//prints -1 good
System.out.println(comp.compare(big, small));//prints 1 why?
System.out.println(comp.compare(big, bsmall));//throws error?!?
}
private static class ComparatorCreator<T extends Comparable<? super T>>{
public Comparator<? extends T> getComparator()
{
return T::compareTo;
}
}
private static class BackwardsInt extends Number implements Comparable<Number>{
private int val;
public BackwardsInt(int v)
{
val=v;
}
@Override
public int compareTo(Number o) {
double d = o.doubleValue()-val;
if(d>0)
return 1;
if(d<0)
return -1;
return 0;
}
public int intValue() {
return val;
}
public long longValue() {
return val;
}
public float floatValue() {
return val;
}
public double doubleValue() {
return val;
}
}
}
解决方案
让我们看看你的ComponentCreator
private static class ComparatorCreator<T extends Comparable<? super T>>{
public Comparator<? extends T> getComparator()
{
return T::compareTo;
}
}
如果稍作更改以使您的错误更清楚
private static class ComparatorCreator<T extends Comparable<? super T>>{
public Comparator<? extends T> getComparator()
{
return (o1, o2) -> {
return o1.compareTo(o2);
};
}
}
您使用的方法参考与我拥有的 lambda 相同,但它使错误更加明显。如果我们一一检查您的样品,我们可以看到以下内容:
comp.compare(bbig, bsmall); // calls bbig.compareTo(bsmall)
comp.compare(bbig, small); // calls bbig.compareTo(small)
comp.compare(big, small); // calls big.compareTo(small)
comp.compare(big, bsmall); // calls big.compareTo(bsmal)
您收到的输出是有意义的,因为big.compareTo()
将调用该类的compareTo()
函数Integer
。
推荐阅读
- opencv - 打开简历:BGR2GRAY 功能如何工作?
- javascript - 将字符串与对象属性的深层嵌套字符串值进行比较的最佳方法?
- python - 多集的可散列类型
- node.js - 如何从 Node、express、Mongoose 和 Ajax 上的帖子中删除评论
- python - 用于计算数字在几个月内增加的 Python 代码,如果它每月增加 10%
- scala - 在 pureconfig 中表示 Either
- scala - 如何为 monaco 编辑器添加 scala 语言支持
- neo4j - 是否可以通过某些属性返回具有关系的节点?
- c - 获取以逗号分隔的输入 + 获取输入的问题
- node.js - 如何更新 npm 版本?