首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >一个完全可重写的compareTo()方法?

一个完全可重写的compareTo()方法?
EN

Stack Overflow用户
提问于 2012-07-30 15:10:26
回答 2查看 314关注 0票数 3

不得不第一次定义相关对象之间的关系,我发现自己花了整个周末在网络上搜索与equals()compareTo()的完全可覆盖的实现相关的信息。由于几乎没有找到有用的信息,我决定找到一个解决方案。我认为以下内容就compareTo()方法而言就是该解决方案的一种体现。我有一个想法,类似的技术可能也适用于equals()方法。

我希望比我更聪明的人可能有时间验证这些发现,并就可能遇到的任何陷阱提供反馈。

代码语言:javascript
运行
复制
// The name chosen for the following class shell ("Base") is intended to
// portray that this compareTo() method should be implemented on a base class
// as opposed to a subclass.
public class Base
implements Comparable<Base>
{
    /**
     * Compares this Base to the specified Object for semantic ordering.
     *
     * @param other The Object to be compared.
     *
     * @return An int value representing the semantic relationship between the
     *         compared objects. The value 0 is returned when the two objects
     *         are determined to be equal (as defined by the equals method).
     *         A positive value may be returned if the "other" object is a
     *         Base and the "exact types" comparison determines this Base to
     *         have a higher semantic ordering than the "other" object, if the
     *         "other" object is not a Base, or if the "other" object is a
     *         subclass of Base who's compareTo method determines itself to
     *         have a lower semantic ordering than this Base. A negative value
     *         may be returned if the "other" object is a Base and the
     *         "exact types" comparison determines this Base to have a lower
     *         semantic ordering than the "other" object or if the "other"
     *         object is a subclass of Base who's compareTo method determines
     *         itself to have a higher semantic ordering than this Base.
     */
    public int compareTo(Base other)
    {
        int relationship = 0;

        if (other == null)
            throw new NullPointerException("other: Cannot be null.");

        if (!this.equals(other))
        {
            if (this.getClass() == Base.class)
            {
                if (this.getClass == other.getClass())
                    relationship = // Perform comparison of exact types;
                else
                    relationship = -1 * other.compareTo(this);
            }
            else
                relationship = 1;
        }

        return relationship;
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-30 15:18:57

这是行不通的。考虑两个类,AB,它们直接扩展Base,但它们的实例永远不相等。然后是两个实例Base a = new A();Base b = new B()。因为this.getClass() == Base.class对于ab都是false,所以a.compareTo(b) == 1b.compareTo(a) == 1也是这种情况。这违反了Comparable的一般合同,即对所有具有可比性的xy执行sgn(x.compareTo(y)) == -sgn(y.compareTo(x))

对于比较对象所涉及的一些细微之处,特别是测试子类之间的相等性,我推荐使用this excellent article

票数 3
EN

Stack Overflow用户

发布于 2012-08-01 13:44:53

正如主题starter中所述,我之所以开始这个项目,是因为缺乏详细说明构建可完全覆盖的compareTo()方法背后的过程的可用信息。我希望你会发现下面的代码就是这样一个实现。补充部分是Ted Hopp,他向我指出了一些我最初忽略的关键元素。

您会发现,RelationalObject的实现没有定义任何元素之间的初始关系,除了那些不属于同一层次结构分支的元素之外,它认为这些元素是不可比较的(当然,也是可覆盖的)。因为这个类可能实现的任何关系都不能考虑到它的派生类的那些状态元素,所以我决定最好把这个任务完全留给用户。

这个类要做的是使更改新子类型(包括那些当前未实现的子类型)的关系行为变得更容易。

因为我在主题starter中表达了对文档的渴望,所以我对每个方法进行了大量注释,希望它能提供一些指导。

我希望有足够时间的人可能愿意提供这些结果的验证。虽然我已经尽了最大努力考虑所有可能的情况,但获得反馈总是很好的。(正面或负面)

代码语言:javascript
运行
复制
public abstract class RelationalObject
implements Comparable<RelationalObject>
{
    /*
     * Compares two RelationalObjects for semantic ordering.
     *
     * @param other The RelationalObject to be compared.
     *
     * @return An int value representing the semantic relationship between the
     *         two RelationalObjects. A value of 0 is returned if the two
     *         objects are determined to be equal. A negative value is
     *         returned if "this" object is determined to have a
     *         lower semantic ordering than the "other" object. A positive
     *         value is returned if "this" object is determined to have a
     *         highter semantic ordering than the "other" object.
     */
    public final int compareTo(RelationalObject other)
    throws ClassCastException, NullPointerException
    {
        if (other == null)
            throw new NullPointerException("other: Cannot be null.");

        int relation = 0;

        if (!this.equals(other))
        {
            if (this.getClass().isAssignableFrom(other.getClass()))
            {
                if (this.getClass() == other.getClass())
                    relation = this.compareToExactType(other);
                else
                    relation = -1 * other.compareTo(this);
            }
            else
            {
                if (other.getClass().isInstance(this))
                    relation = this.compareToSuperType(other);
                else
                    relation = other.compareToForeignType(this);
            }
        }

        return relation;
    }

    /*
     * Compares two RelationalObjects with the exact same class type for
     * semantic ordering. The comparison may be based upon any of the class
     * state elements so long as the compareTo() method contract is not
     * broken.
     *
     * @param exact The RelationalObject with exactly matching type to be
     *              compared.
     *
     * @return An int value representing the semantic relationship between the
     *         two RelationalObjects.
     */
    protected abstract int compareToExactType(RelationalObject exact);

    /*
     * Compares two RelationalObjects not within the same hierarchical branch
     * for semantic ordering. The comparison may be based upon only those
     * state elements common to both objects (i.e. A comparison must be made
     * between each element and the pair's common ancestor). Should the two
     * results be equal, a ClassCastException must be thrown as the objects do
     * not contain enough distinct information to be further compared.
     *
     * @param foreign The RelationalObject from a foreign hierarchical branch
     *                to be compared.
     *
     * @return An int value representing the semantic relationship between the
     *         two RelationalObjects.
     */
    protected abstract int compareToForeignType(RelationalObject foreign);

    /*
     * Compares two RelationalObjects within the same class hierarchical
     * branch for semantic ordering. The comparison may be based upon any of
     * the class state elements so long as the compareTo() method contract is
     * not broken.
     *
     * @param upper The RelationalObject within the same heirarchical branch
     *              and with lesser definition to be compared.
     *
     * @return An int value representing the semantic relationship between the
     *         two RelationalObjects.
     */
    protected abstract int compareToSuperType(RelationalObject upper);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11716828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档