Sort() 和 CompareTo() 方法的内部工作原理

2023-11-30

我一直在试图弄清楚如何CompareTo()方法在内部有效,但我失败了。我搜索过这个网站并阅读了一些帖子,我想我已经在 MSDN 上看到了关于这个主题的所有内容,但我似乎不明白。一个 MSDN 示例:

public int CompareTo(object obj)
{
    if (obj == null)
    {
        return 1;
    }

    Temperature otherTemperature = obj as Temperature;
    if (otherTemperature != null)
    {
        return this.temperatureC.CompareTo(otherTemperature.temperatureC);
    }
    else
    {
        throw new ArgumentException("the object is not a temperature");
    }
}

这是 MSDN 的实现示例CompareTo()方法。我明白这一点,我明白如何IComparable接口有效,如果我理解正确的话,当我使用ArrayList.Sort()方法。

我不明白的是:程序什么时候传递参数CompareTo(object obj)方法?或者换句话说,如何Sort()方法工作?我的意思是,这段代码正在将一个温度实例与另一个温度实例进行比较,但是程序何时或如何获取第二个温度实例以进行比较?我希望我的问题有意义。

我尝试过打印到屏幕上CompareTo()过程,所以也许我可以对输出进行逆向工程,但我自己更加困惑。

EDIT: 也许如果我一步一步来,我可以更好地解释自己。假设我有 3 个温度对象:34、45、21ArrayList。当我打电话时ArrayList.Sort(), 是个CompareTo()方法称为类似34.CompareTo(45)?进而45.CompareTo(21)?第一次比较时返回的整数为 1,第二次比较时返回的整数为 -1?如果我只定义了这些整数,那么这些整数是如何返回的CompareTo()仅当 obj(参数)为 null 时才返回 1 的方法?我没有定义任何返回 -1 或 0 的内容。就好像我正在实现一个已经实现的方法。定义一个CompareTo()方法已定义为返回 -1、0 和 1。


让我们从基本想法开始。

CompareTo 的目的是什么?

42 到 1337 是多少。是 42...比...更棒, 少于 or equal to 1337?

这个问题及其答案的模型是CompareTo方法中的IComparable<T> and IComparable接口。为了A.CompareTo(B),该方法可以返回:

  • A is 比...更棒B:大于0的整数值。
  • A is 少于B:小于0的整数值。
  • A is equal toB:等于 0 的整数值。

而且当然,IComparable不限于整数。你可以实施IComparable比较您认为应该具有可比性的任意两个对象。例如,字符串:

什么是“犰狳”到“十二宫”:“犰狳”是...比...更棒, 少于 or equal to“十二生肖”?

答案取决于您对大于、小于和等于的定义。对于字符串,通常的顺序是出现的单词later字典中是比...更棒较早出现的单词。

CompareTo 如何帮助排序?

好的,现在您知道如何比较任意两个对象了。这对于许多算法都很有用,但主要是排序和排序算法。以一个非常简单的排序算法为例:愚蠢的排序。这个想法是:

查看数组中的两个相邻元素 A 和 B。
当 A 当A>B时:交换A和B,并返回到前一对。
当我们到达终点时,我们就完成了。

您会看到,要进行排序,必须有一种方法来确定两个元素中哪一个更大。那就是那里IComparable<T>发挥作用。

public static void StupidSort<T>(T[] array)
            where T : IComparable<T>
{
    int index = 0;
    while (index < array.Length)
    {
        if (index == 0 ||
            array[index - 1].CompareTo(array[index]) <= 0)
        {
            index++;
        }
        else
        {
            Swap(array, index - 1, index);
            index--;
        }
    }
}

当 CompareTo 总是返回 1 时会发生什么?

你当然可以编程CompareTo返回任何你想要的东西。但如果你搞砸了,那么你的方法就不再能回答问题了what is this to obj?始终返回 1 意味着对于任何 A 和 B,A 始终大于 B。这就像说:20 大于 10and10 大于 20。这没有意义,结果是你所做的任何排序也没有任何意义。垃圾进垃圾出。

对于三个给定的对象 A、B 和 C,游戏规则为:

  • A.CompareTo(A)必须返回 0 (A 等于 A).
  • If A.CompareTo(B)返回 0,则B.CompareTo(A)返回 0 (如果 A 等于 B,则 B 等于 A).
  • If A.CompareTo(B)返回 0,并且B.CompareTo(C)返回 0,则A.CompareTo(C)返回 0 (如果 A 等于 B,且 B 等于 C,则 A 等于 C).
  • If A.CompareTo(B)返回一个大于0的值,然后B.CompareTo(A)返回一个小于 0 的值 (如果 A 大于 B,则 B 小于 A).
  • If A.CompareTo(B)返回一个小于 0 的值,然后B.CompareTo(A)返回一个大于 0 的值 (如果 A 小于 B,则 B 大于 A).
  • If A.CompareTo(B)返回一个大于 0 的值,并且B.CompareTo(C)返回一个大于0的值,然后A.CompareTo(C)返回一个大于 0 的值 (如果A大于B,且B大于C,则A大于C).
  • If A.CompareTo(B)返回一个小于 0 的值,并且B.CompareTo(C)返回一个小于 0 的值,然后A.CompareTo(C)返回一个小于 0 的值 (如果 A 小于 B,且 B 小于 C,则 A 小于 C).
  • null总是小于任何非空对象。

如果您的实现不遵守这些(简单且逻辑的)原则,那么排序算法实际上可以做任何事情,并且可能不会给出您期望的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Sort() 和 CompareTo() 方法的内部工作原理 的相关文章

随机推荐

  • 根据字典替换文本

    我需要做一些类似于这篇文章的事情 但有所不同 这就是我问的原因 unix shell 用字典替换 我有一本字典 dict txt 它是用空格分隔的 内容如下 V7动力 B6 广达 从某种意义上说 第一列是键 第二列是值 我有一个用户文件 u
  • 2 个意图过滤器,1 个活动 - 哪个打开了它?

    有没有办法知道哪个 Intent Filter 负责启动一个在 AndroidManifest xml 中定义了两个 Intent Filter 的 Activity 我想要一套稍微不同的逻辑 但还不足以需要一个全新的活动 Thanks 没
  • 如何在 kivy 中按下按钮时更改按钮的背景颜色?

    我的应用程序有一个带有默认背景颜色的按钮 我只想将其背景颜色更改为另一种颜色on press事件 您可能会认为它类似于 html 的已访问和未访问的超链接 即当单击链接时 它会更改其颜色 我的尝试 usr bin kivy import k
  • 从评论中提取电话号码

    我有一个专栏 其中有评论 超过 5000 个案例 这些评论有文字 数字 日期等等 我需要从这些评论中获取电话号码 每条评论的电话号码都是随机的 所以LEFT MID or RIGHT不管用 我达到的最接近的结果是 Kutools EXTRA
  • 重新审视浮点比较

    这个话题在 StackOverflow 上已经出现过很多次了 但我相信这是一个新的话题 是的 我已经读过布鲁斯 道森的文章 and 每个计算机科学家都应该了解的浮点运算知识 and 这个很好的答案 据我了解 在典型的系统上比较浮点数是否相等
  • 为什么接口方法调用比具体调用慢?

    当我发现抽象类和接口之间的区别时 我想到了这个问题 在这个帖子我开始知道接口很慢 因为它们需要额外的间接 但我不知道接口需要什么类型的间接 而不是抽象类或具体类所需的间接类型 请澄清一下 提前致谢 有许多性能神话 有些可能在几年前是正确的
  • 如何使用 jQuery 防止 ajax 请求遵循重定向

    我使用 jQuery ajax 函数访问 Web 服务 但服务器没有返回带有描述问题的状态代码的响应 而是将请求重定向到带有 200 标头的页面 描述问题 我无法对此进行任何更改 因此我需要以某种方式在客户端上解决它 例子 请求转到某个未找
  • 如何使用Google Drive API获取最后修改的用户信息?

    In Google Apis Drive v2 Data File类它只提供最后修改用户的名称 如何获取用户的完整信息 如电子邮件 用户 ID 等 var service new DriveService auth Google Apis
  • 如何在 Mac OS ( OS X 10.10) 中安装 php-cgi 作为插件?

    我想在 My 上进行 PHP 工作Mac book 然而 我安装后PHP风暴 并告诉PHP解释器的位置 它会导致错误 php cgi not found Please ensure that configured PHP Interpret
  • 如何从 Visual Studio Team Services 将静态网站部署到 Azure

    我有一个想要部署的现有网站Azure using Visual Studio 团队服务 该网站由静态文件组成 不涉及 ASP NET 或其他任何内容 在 Visual Studio Team Services 中 我创建了一个执行的构建np
  • cv::add 在 openCV 中不起作用

    我尝试构建 10 帧的平均值 因此我尝试了 cv Mat frame outf resultframe1 resultframe2 VideoCapture cap 1 cap gt gt frame resultframe1 Mat ze
  • 重写 JS 中的图像构造函数?

    是否可以覆盖ImageJS 中的构造函数 因此 例如 每次new Image 创建后 一条消息会写入控制台吗 尝试这个 function var OriginalImage window Image window Image functio
  • Cocoa:带有用于切换选项卡的工具栏图标的选项卡视图

    各种首选项对话框 Safari Mail Xcode4 和任何使用 NSPreferences 的对话框 和 Xcode4 的组织器使用让人想起选项卡视图的东西 只不过它使用工具栏按钮在选项卡之间切换 这些按钮被 按下 实现这种选项卡视图的
  • 到期时自动刷新 ASP.NET 输出缓存

    我有一些昂贵的页面 我使用 ASP NET 输出缓存进行缓存 如下所示 OutputCache Duration 3600 VaryByParam none 显然 缓存将在 3600 秒 1 小时 后过期 下一个碰巧加载该页面的可怜人将不得
  • Spring 与 Jackson ObjectMapper 和 Java 8 Time 集成 (JSR-310)

    我正在努力配置 Spring Integration DSL 转换器使用的 自定义 ObjectMapper 我收到一个java time Instant我想将其解析为对象属性的 json 表示形式 IE 类型 测试 来源 测试 时间戳 e
  • 重用缓存的 Spark RDD

    Spark 是否有可能在另一个应用程序中 或在同一应用程序的另一个运行中 重用缓存的 RDD JavaRDD
  • 如何从 Capistrano 运行 rake 任务?

    我已经有一个可以在生产服务器上部署我的应用程序的deploy rb 我的应用程序包含一个自定义 rake 任务 lib tasks 目录中的 rake 文件 我想创建一个 cap 任务来远程运行该 rake 任务 更明确一点 在你的 con
  • 发送 APN 返回 BadDeviceToken,DeviceToken 格式应该是什么?

    我的后端使用 Node js 和 Express js 使用npm apn包 它使用 Apple 的新提供商身份验证令牌 iOS应用程序获得许可并将收到的32字节设备令牌发送到后端 编码为base64字符串 但是 当尝试使用设备令牌 编码为
  • SpringMVC-FileUpload - 客户端发送的请求在语法上不正确

    我见过几个关于同一主题的 qt 但我没有发现这个错误的任何线索 我正在研究 POC 并点击下面的链接 http spring io guides gs uploading files 正如上面教程中提到的 在独立模式下 spring emb
  • Sort() 和 CompareTo() 方法的内部工作原理

    我一直在试图弄清楚如何CompareTo 方法在内部有效 但我失败了 我搜索过这个网站并阅读了一些帖子 我想我已经在 MSDN 上看到了关于这个主题的所有内容 但我似乎不明白 一个 MSDN 示例 public int CompareTo