IComparable interface and IComparer interface
In order to be able to sort the data items, it is necessary to determine the relative position of the two data items in the list, that is, to determine the "size" relationship between the two objects. Generally speaking, there are two ways to define the size relationship: The
first way is for the object itself . In order for an object to perform comparison operations by itself, the object must implement an IComparable
interface, that is , it must have at least one CompareTo()
member.
System.IComparable
There is a method in the interface, as follows:
int CompareTo(object obj);
It returns a positive, 0, or a negative number based on the "size" of the current object and the object to be compared.
All simple value types (e.g. int
, double
, decimal
etc.), string and enumerated classes, implements this interface; any type of user-defined type as long as the value is ordered, this interface can be implemented.
The second way is to provide an external comparator . In order to be able to compare the size of the object, a comparator can be provided, which implements an ICompare
interface.
System.Collections.IComparer
There is a method in the interface, as follows:
int Compare(object obj1, object obj2);
It returns a positive, 0, or a negative number based on the "size" of the first object and the second object. E.g:
int Compare(object obj1, object obj2){
return (abj1 as Book).price - (obj2 as Book).price;
}
The above code indicates that the books are sorted in ascending order according to the size of the book's price. A value less than 0 means that the first object is "smaller" than the second object, and 0 means that the two objects are "equal in size", and a positive number means that the first object is "greater than" the second object.
Use the Array class to sort and find
System.Array
The class is the class used to sort and search the array. Array
The class provides a Sort()
sum BinarySearch()
, which can be used for sorting and searching, and also provides a Reverse()
method to reverse the order.
1.Array.Sort()及Reverse
Array.Sort()
The method can realize the sorting of a one-dimensional array. The following forms are commonly used:
public static void Sort(Array); // 对数组元素排序, 每个元素要求实现IComparable
public static void Sort(Array keys, Array values); // 根据keys数组对values排序
public static void Sort(Array, IComparer); // 对数组排序, 使用外部比较器
public static void Sort(Array keys, Array values, IComparer); // 根据keys数组对values排序, 排序时, 使用外部比较器
Array.Reverse()
Method, can be used to reverse the order of the entire array:
public static void Reverse(Array); // 对数组排序, 每个元素要求实现IComparable
2. The generic method of Array.Sort()
Array.Sort()
There is also a generic method, method Sort<T>(T[])
. It can also take IComparer<T>
parameters. In addition, it can also take a Comparsiom commission. The prototype of the commission is:
public delegate int Comparsion<in T>(T x, T y);
An easy way to write delegate parameters is to use Lambda expressions, for example:
Array.Sort<Person>(people, (p1, p2) => p1.Age - p2.Age);
Indicates that the array of people is sorted by age from smallest to largest.
3.Array.BinarySearch()
Array.BinarySearch()
The method can realize the element search in a bunch of arrays that have been sorted, and the following forms are commonly used:
public static int BinarySearch(Array, object); // 在数组中进行查找对象object
public static int BinarySearch(Array, object, IComparer); // 使用外部比较器
BinarySearch()
Pay attention to use : the array must be sorted before executing BinarySearch().
Example:
using System;
public class Test
{
public static void Main(string[] args){
string[] ary = {
"Apple", "Pearl", "Banana", "Carrot" };
Show(ary);
Array.Sort(ary);
Show(ary);
int it = Array.BinarySearch(ary, "Pearl");
Console.WriteLine(it);
Array.Reverse(ary);
Show(ary);
}
public static void Show(object[] ary){
foreach (object obj in ary)
Console.Write(obj + " ");
Console.WriteLine();
}
}
operation result:
Sorting and searching in collections
There are also some mechanisms for sorting and searching in the collection class, for example:
- ① There are
Contains()
methods for searching in many classes . - ② Many
ToArray()
methods in the class can be converted into an array, and then sorted and searched. - ③ A new ArrayList and SortedList object can be constructed from other collections, and then sorted and searched.
1.ArrayList的Sort( )及BinarySearch( )
ArrayList
The methods in are related to sorting and searching, the common ones are:
public virtual void Sort();
public virtual void Sort(IComparer);
public virtual int BinarySearch(object);
public virtual int BinarySearch(object, IComparer);
For a collection class, you can construct an ArrayList
instance:
public ArrayList(ICollection);
In this construction method, an object of a collection class is copied and a ArrayList
class is generated .
ArrayList
It also provides Adapter()
methods to include other IList
objects ArrayList
.
public static ArrayList Adapter(IList);
Adapter
IList
The content that is not copied , it is only for IList
creating ArrayList
packaging; therefore, IList
making changes to it will also affect it ArrayList
. This method can be used to ArrayList
provide general classes Reverse
, BinarySearch
and Sort
methods. However, performing these general operations through this package is less efficient than applying these operations directly on IList.
2.SortedList
SortedList
The objects of the class will be automatically sorted when adding elements. An object (including objects) can be copied and sorted
by creating an SortedList
instance .IDictionary
SortedList
public class Test
{
static void Main(string[] args) {
Person[] Persons = {
new Person("Liu", true, 21),
new Person("Zhang", true, 18),
new Person("Tang", false, 23),
new Person("Lu", false, 21)
};
Random rnd = new Random();
SortedList list1 = new SortedList();
foreach (Person r in Persons)
list1.Add(r.ToString(), "Room:" + rnd.Next(1000));
Person.PrintKeysAndValues(list1);
SortedList list2 = new SortedList(list1, new MyComparer());
Console.WriteLine("111111111111111");
Person.PrintKeysAndValues(list2);
}
}
public struct Person : IComparable
{
public string Name;
public bool Sex;
public int Age;
public Person(string name, bool sex, int age) {
this.Name = name;
this.Sex = sex;
this.Age = age;
}
public int CompareTo(object obj) {
if (!(obj is Person))
throw new System.ArgumentException();
Person rec = (Person)obj;
if (this.Age > rec.Age) return 1;
else if (this.Age == rec.Age) return 0;
return -1;
}
public override string ToString() {
return "Name: " + Name + "; Sex: " + Sex + "; Age: " + Age;
}
public static void PrintKeysAndValues(SortedList myList) {
IDictionaryEnumerator myEnumerator = myList.GetEnumerator();
while (myEnumerator.MoveNext())
Console.WriteLine("{0}:\t\t{1}", myEnumerator.Key, myEnumerator.Value);
Console.WriteLine();
}
}
public class MyComparer : IComparer
{
public int Compare(object obj1, object obj2) {
if (!(obj1 is Person) || !(obj2 is Person))
throw new System.ArgumentException();
Person rec1 = (Person)obj1;
Person rec2 = (Person)obj2;
return rec1.Name.ToLower().CompareTo(rec2.Name.ToLower());
}
}