我一直在试图找出如何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()
过程,所以也许我可以反向工程的输出,但我感到很困惑,甚至更多。
编辑 :也许,如果我走一步看一步,我可以更好地解释自己。 假设我有3点温度的对象:34,45,21中的ArrayList
。 当我打电话ArrayList.Sort()
是CompareTo()
称为像法34.CompareTo(45)
然后45.CompareTo(21)
返回的整数是1的第一比较和第二-1? 又是如何的整数得到恢复,如果我只定义CompareTo()
方法返回1只有在OBJ(参数)为空? 我没有定义什么返回-1或0。就好像我正在实施包括已经实现的方法。 限定CompareTo()
时,它的已定义为返回-1,0和1的方法。
让我们先从基本概念。
什么是的CompareTo的目的是什么?
什么是42到1337年是42 ... 大于 , 小于或等于 1337?
这个问题和答案其由建模CompareTo
在方法IComparable<T>
和IComparable
接口。 对于A.CompareTo(B)
该方法可以返回:
- A是大于 B:一个整数值大于0。
- A 小于 B:小于0的整数值。
- A 等于 B:一个整数值等于0。
当然还有, IComparable
不限于整数。 您可以实现IComparable
到,你认为应该是可比的任何两个比较对象。 例如,字符串:
什么是“犰狳”到“梦幻西游”:是“犰狳” ... 大于 , 小于或等于 “十二生肖”?
答案取决于你的大于,小于和等于定义。 对于字符串通常的顺序是,这将在以后的字典发生的一句话就是比之前就已发生更大的词。
如何帮助的CompareTo排序?
好了,现在你知道你可以比较任意两个对象。 这是很多算法是有用的,但主要是分类和排序算法。 举例来说,一种非常简单的排序算法: 愚蠢的排序 。 我们的想法是:
看看在你的阵列,A和B两个相邻的元素
当A <= B:前进到下一对。
当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
返回你想要的任何东西。 但是,如果你搞砸了,那么你的方法不再回答的问题是什么this
对obj
? 总是返回一个1是指对于任何A和B,A总是大于B.这就像说:20大于10 和 10大于20,这没有意义,其结果是,任何你排序这样做也没有任何意义。 垃圾进垃圾出。
游戏的规则是,对于给定的3个对象A,B和C:
-
A.CompareTo(A)
必须返回0(A等于A)。 - 如果
A.CompareTo(B)
返回0,然后B.CompareTo(A)
返回0( 如果A等于B,则B等于A)。 - 如果
A.CompareTo(B)
返回0,和B.CompareTo(C)
返回0,然后A.CompareTo(C)
返回0( 如果A等于B,和B等于C,则A是等于C )。 - 如果
A.CompareTo(B)
返回一个值大于0,则B.CompareTo(A)
返回一个小于0的值( 如果A大于B,则B是小于A)。 - 如果
A.CompareTo(B)
返回小于0的值,则B.CompareTo(A)
返回一个大于0的值( 如果A小于B,则B是大于A)。 - 如果
A.CompareTo(B)
返回一个值大于0,和B.CompareTo(C)
返回一个大于0的值,然后A.CompareTo(C)
返回一个大于0的值( 如果A大于B,和B是大于C,则A是大于C)。 - 如果
A.CompareTo(B)
返回小于0的值,并且B.CompareTo(C)
返回一个值小于0,则A.CompareTo(C)
返回一个小于0的值( 如果A小于B,和B小于C,则A是小于C)。 -
null
总是比任何非空的对象较少。
如果您的实施不遵守这些(简单的和逻辑的)原则,然后排序算法可以从字面上做任何事情,而且很可能不给你所期望的结果。
如果要比较a
到b
,你说:
int result=a.CompareTo(b);
即,第一比较操作数是this
,第二个是传递给函数的参数。
然后,当你排序的阵列,无论算法的使用,你必须比较元素结合在一起,把他们作为this
和obj
到object.CompareTo
(或该函数的重载可行)。
排序方法是独立于的CompareTo
方法。 我不知道是干什么用的排序算法,但我猜这件事情就像一个快速排序(OBV不冒泡排序)。 如果你有兴趣在这些算法维基百科记载加以详细。
所述CompareTo
方法是简单地比较相同类型的对象的装置。 它定义了许多常见的.NET类型的开始与和可重写做(事您创建)的自定义对象之间的比较。 基本上你从类型的对象A传递给它类型A的第二对象,并且返回值调用它表示如果两者相等,或者如果一个比另一个大。
这是最好想CompareTo
的效用函数。 它的存在,所以你能做的使用提供与普通.NET数据结构的排序方法的自定义比较。 如果没有类似的东西,你会写自己的排序算法,以比较您所创建的类型。 它的目的仅仅是使排序方法为可重复使用的/可扩展的。
总之,排序需要你的ArrayList的两个元素,并为第一要素调用的CompareTo,并通过第二个元素作为参数,如下所示:
element1.CompareTo(element2)
如果元素1是在element2以下,0,如果它们相等,正否则值的CompareTo返回负值。 排序使用此返回值,嗯,做一些整理。 然后重复这个过程,后面两个要素,做多一些排序,依此类推,直到ArrayList的排序。 搜索“排序算法”,以获取有关这一过程的详细信息。
有不同的排序算法。 但是,不管是什么有时候会有这样的算法必须决定哪些元素是较大的,这是当点CompareTo
被调用。
a.CompareTo(b) < 0;
如果a和b是Integers
(或伪),你也可以使用:
a < b
我想你会发现a < b
在大量的伪代码或整数排序算法的例子符号。 CompareTo
的方法IComparable<T>
是一个面向对象的实现-或符号。