標籤:style blog http color 使用 java ar strong 檔案
在項目中經常會用到字串比較,但是有時候對字串的操作比較多,規則各異。比如有的地方我們需要用定序,有的地方需要忽略大小寫,我們該如何寫一個比較容易操作的比較方法呢?重新實現IComparer介面不失為一個好辦法。
IComparable.CompareTo 方法
在MSDN上是這麼解釋(機器翻譯過來)的:
IComparable介面:定義一種特定於類型的通用比較方法,實值型別或類通過實現此方法對其執行個體進行排序。
IComparer介面:公開一種比較兩個對象的方法。
詳細理解就是:
在預設情況下,對象的Equals(object o)方法(基類Object提供),是比較兩個物件變數是否引用同一對象。
我們要必須我們自己的對象,必須自己定義對象比較方式。
IComparable和ICompare 介面是.net framework 中比較對象的標準方式,這兩個介面之間的區別如下:
IComparable是標識這個類型具有比較的能力,可以比較該對象和另一個對象。一般情況下,我們使用 IComparable 給出類的預設比較代碼,使用其他類給出非預設的比較代碼。中文應該叫“可比較對象”。
IComparer是在一個單獨的類中實現,是指當前對象可以用來比較任意兩個對象,而當前對象本身不參與計算,中文應該叫“比較子”。
CompareTo:IComparable提供了一個方法int CompareTo(object obj)。這個方法接受一個對象,將當前執行個體的對象與同一類型的另一個對象進行比較,並返回一個整數,該整數指示當前執行個體在排序次序中的位置是位於另一個對象之前、之後還是與其位置相同。
Compare:IComparer 也提供了一個方法 Compare().這個方法接受兩個對象,返回一個整型結果,這與 CompareTo()相同。
IComparable介面
比如:有一個預設執行個體對象person1,需要和person2判斷,判斷person1是否比person2更年老或年輕,實際上,這個方法返回一個int,所以可和下面的代碼說明person1更年老還是更年輕。
1 if(person1.CompareTo(person2) == 0) 2 2 { 3 3 Console.WriteLine("Same age");//年齡一樣,person1和person2比較後返回0 4 4 } 5 5 else if(person1.CompareTo(person2) > 0 ) 6 6 { 7 7 Console.WriteLine("person1 is older");//如果person1>person2,person1和person2比較後返回正整數,person1比person2年齡大 8 8 } 9 9 else10 10 {11 11 Console.WriteLine("person1 is younger");//如上述if不成立,person1<person2,person1和person2比較後返回正整數,person1比person2年齡小12 12 }
IComparer介面
同樣適用person來做例子
比如:有一個對象person1,需要和person2判斷,判斷person1是否比person2更年老或年輕,實際上,這個方法同樣也是返回一個int,但是我們使用的是另外的介面(IComparer)的Compare來寫,所以可和下面的代碼說明person1更年老還是更年輕。
1 if(personComparer.Compare(person1,person2) == 0) 2 { 3 Console.WriteLine("same age"); 4 } 5 else if(personComparer.Compare(person1,person2) > 0 ) 6 { 7 Console.WriteLine("person 1 is older"); 8 } 9 else10 {11 Console.WriteLine("person1 is younger");12 }
在這兩種情況下,提供給方法的參數(person1、person2)是system.object類型。也就是說,可以比較任意類型的兩個對象。所以,在返回結果之前,通常需要進行某種類型比較,如果使用了錯誤的類型,還會拋出異常。實際上,我們是使用泛型介面IComparable<T>,可以省略對象轉換。
對象之間的大小比較,在開發過程中用的還是很多的,比如:string是一個可比較對象,它具有和另外一個String比較的能力,它會使用字母序進行比較。但是,有時候我們的一些邏輯需要一些特殊的比較方法。例如:WindowsExplorer 中的檔案排序會認為”File10.txt" > "File2.txt"。這時候,我們就需要寫一個特殊的IComparer對象實現這些特定的邏輯。
-----------------------------------------------------------------------------分割線-----------------------------------------------------------------------------
IComparable.CompareTo(Object x)的比較方式:
compareTo()的傳回值是整數型別,它是先比較對應字元的大小(ASCII碼順序),如果第一個字元和另一個參數的第一個字元不等,結束比較,返回他們ASCII碼之間的差值,如果第一個字元和另一個參數的第一個字元相等,則以第二個
字元和另一個參數的第二個字元做比較,以此類推,直至比較的字元或被比較的字元有一方全比較完,這時就比較字元的長度.
舉個Java的例子說明:
String s1 = "abc";
String s2 = "abcd";
String s3 = "abcdefg";
String s4 = "1bcdfg";
String s5 = "cdfg";
System.out.println( s1.compareTo(s2) ); // -1 (前面相等,s1長度小1)
System.out.println( s1.compareTo(s3) ); // -4 (前面相等,s1長度小4)
System.out.println( s1.compareTo(s4) ); // 48 ("a"的ASCII碼是97,"1"的的ASCII碼是49,所以返回48)
System.out.println( s1.compareTo(s5) ); // -2 ("a"的ASCII碼是97,"c"的ASCII碼是99,所以返回-2)
-----------------------------------------------------------------------------分割線-----------------------------------------------------------------------------
C# 如何?compareTo()方法
那麼在什麼時候使用Icomparable.CompareTo(object obj)方法呢?
如果一個類實現了Icomparable介面,就可以重寫Icomparable介面中的CompareTo(object obj)方法,假設集合中有幾個學員對象,要按學員的姓名進行排序,那麼就可以重寫CompareTo方法按姓名排序,但如果又想按年齡排序了怎麼辦?CompareTo方法只能重寫一次啊,這時就可以用到Icompare了。Icompare就叫做比較子,集合預設的Sort()排序方法有種重載的參數就是Icompare比較子對象。
像所有集合類一樣,它允許您對所有實現了IComparable介面的對象進行排序。在下一個例子中,您將修改NameCompare類以實現IComparable的泛型介面:
public class NameCompare: IComparable<Student>
實現IComparable<Student>介面,NameCompare對象必須提供CompareTo()方法:
1 class NameCompare:IComparer<Student> //姓名升序 2 { 3 public int Compare(Student x, Student y) 4 { 5 return x.Name.CompareTo(y.Name); 6 } 7 } 8 9 class NameCompare1 : IComparer<Student> //姓名降序10 {11 public int Compare(Student x, Student y)12 {13 return y.Name.CompareTo(x.Name);14 }15 }16 17 class AgeCompare : IComparer<Student> 18 {19 public int Compare(Student x, Student y) 20 {21 return x.Age.CompareTo(y.Age);22 }23 }
要排序的時候:
private void button3_Click(object sender, EventArgs e){ init(); students.Sort(new NameCompare()); //姓名升序,Sort方法的參數就是實現了Icompare介面的類的對象 show(students);}private void button4_Click(object sender, EventArgs e){ init(); students.Sort(new NameCompare1()); //姓名降序 show(students);}private void button5_Click(object sender, EventArgs e){ init(); students.Sort(new AgeCompare()); show(students);}
轉寄請說明出處:http://www.cnblogs.com/abc1069/p/3993818.html
C# IComparable介面、IComparer介面和CompareTo(Object x)方法、Compare()方法