当前位置: 首页 > 面试题库 >

应该将可比与其他类型进行比较吗?

党佐
2023-03-14
问题内容

我想知道是否存在以下有效用例:

class Base {}

class A implements Comparable<Base> {
    //...
}

接受类型为where
的集合似乎是一种常见的模式(请参见Collections中的许多示例)。T``T extends Comparable<? super T>

但是,compareTo()与基类进行比较时,在技术上似乎无法履行合同,因为无法确保另一类不会通过矛盾的比较来扩展基数。考虑以下示例:

class Base {
    final int foo;
    Base(int foo) {
        this.foo = foo;
    }
}

class A extends Base implements Comparable<Base> {
    A(int foo) {
        super(foo);
    }
    public int compareTo(Base that) {
        return Integer.compare(this.foo, that.foo); // sort by foo ascending
    }
}

class B extends Base implements Comparable<Base> {
    B(int foo) {
        super(foo);
    }
    public int compareTo(Base that) {
        return -Integer.compare(this.foo, that.foo); // sort by foo descending
    }
}

我们有两个类,它们Base使用不遵循共同规则的比较进行扩展(如果存在共同规则,则几乎可以肯定在中实现Base)。但是,下面的破碎类将被编译:

Collections.sort(Arrays.asList(new A(0), new B(1)));

只接受不安全T extends Comparable<T>吗?还是有一些用例可以验证通配符?


问题答案:

这个问题问得好。首先,让我们从Collections使用诸如

binarySearch(List<? extends Comparable<? super T>> list, T key)

确实,为什么不只是

binarySearch(List<? extends Comparable<T>> list, T key)

这样做的原因是PECS原则:生产者扩展,消费者超级。怎么binarySearch办?它从列表中 读取 元素,然后通过 其值 传递
compareTo函数进行比较。由于列表读取元素,因此它充当了生产者,因此,第一部分即生产者扩展。这很明显,那么“超级消费者”部分又如何呢?

Consumer
Super本质上意味着,如果仅要将值传递给某个函数,则不必在乎它是否接受对象的确切类型还是对象的某些超类。因此,binarySearch声明的意思是:只要可以将任何内容传递给compareTolist元素的方法,我都可以查找任何内容。

在排序的情况下,并不是很明显,因为仅将元素相互比较。但是即使那样,如果Base实际上实现了Comparable<Base>(整个比较是否完成)A并且B仅仅扩展Base而又不以任何方式进行比较又会怎样呢?然后,您将无法对A和的列表进行排序,B因为它们分别未实现Comparable<A>Comparable<B>。每次子类化时,您都必须重新实现整个接口!

另一个例子:如果有人想对包含某个类实例甚至不扩展您的实例的列表进行二进制搜索,该怎么办Base

class BaseComparable implements Comparable<Base> {
    private final Base key;
    // other fields

    BaseComparable(Base key, ...) {
        this.key = key;
        // other fields initialization
    }

    @Override
    public int compareTo(Base otherKey) {
        return this.key.compareTo(otherKey);
    }
};

现在,他们希望使用的实例A作为此二进制搜索的关键字。由于? super T部分原因,他们只能这样做。请注意,此类不知道键是a
A还是a,B因此无法实现Comparable<A/B>

至于您的示例,我想这只是一个糟糕的设计示例。不幸的是,我认为在不破坏PECS原理和/或限制Java泛型已经有限的功能的情况下,无法防止此类情况。



 类似资料:
  • 首先要明确一点的是,没有最好,只有最合适。前端框架并不是所谓 注:本文一些数据收集时间为16-12-31 因为大部分教程都是付费的,所以教程数量的多少在侧面反映了框架的市场需求,如果框架冷门用的人不多,那必然不会有人去为其开发教程。

  • 请原谅我在这里缺乏理解,因为我已经进入了三天的冬眠期。 我正在尝试在一个实体上添加验证,这需要将它们与另一个实体进行比较。 例如,以一个人为例。一个人可以有许多身体部位,但最多有两个手臂类型的身体部位(变异除外)。为了验证这一点,在插入新的车身部件时,我需要将其与给定人员的其他车身部件进行比较,并验证该类型的最大值是否已经达到。 我一直在研究Hibernate提供的约束/验证内容,但似乎没有一个涵

  • 问题内容: 如何检查数据库中是否存在Blob的重复项。我的数据库中有文档表,但是我不确定如何检查其中一个是否重复。我知道您应该使用dbms_lob.compare函数,但是在阅读了有关该主题的一些线程和文章之后,我仍然不明白这一点。 Documents表具有document_id列和data(blob)列。如何检查document_id = 1是否重复? 问题答案: “如果dbms_lob.com

  • 我想用Java做一个程序来比较两个三角形。比较角度的顺序无关紧要,我知道我可以用语句来做,但有没有其他更有效的方法来比较3个角度和另外3个角度,因为三角形旋转并不重要,因为完全相同?(Java语言)

  • 我创建了一个,当调用变量为ISE时,它会读取相关数据的表。但是,如果我尝试将与另一个对象进行比较,无法正确读取。我想告诉脚本,如果现有CSV中的任何行与匹配,则不会将数据导出到CSV,换句话说,跳过CSV文件中的重复行。CSV可能有也可能没有多行。

  • 问题内容: 我得到的错误就在这行 。 该怎么办?其他逻辑还可以吗? 我想做的是有一个A列表和一个B列表,其中一个属性与id相同;尽管变量名不同。即在和在B。现在我将两个列表都放在ListAll中,并在相同的变量id / bid上对它们进行排序。我有A和B实现可比性。 和我的listAll是对象类型? 我该怎么做?谢谢。 问题答案: 您可以添加一个通用基类并在那里进行比较,如下所示: