基元和 IComparable 接口
Primitives and IComparable interface
在 Java 中,如果我想独立于数据类型对任何数据进行排序,我会使用 Comparable 接口,我发现我们在 C# 中有类似的接口,所以我有简单的排序算法:
public static void Sort(IComparable[] arr)
{
bool swap = true;
while (swap)
{
swap = false;
for (int i = 0; i < arr.Length - 1; i++)
{
if (Less(arr[i + 1], arr[i]))
{
Exchange(arr, i, i + 1);
swap = true;
}
}
}
}
所以我可以对任何实现 IComparable
接口的对象进行排序,但我不能对任何原始数据类型进行排序,而且据我所知,C# 没有像 int -> Integer 这样的原始数据类型的包装器类型,但是它有一些像 Int32 这样的结构实际上实现了 IComparable 接口,但由于某些原因我仍然不能使用它,例如:
static void Main(string[] args)
{
Int32[] ints = { 5, 2, 9, 0, 3};
BubbleSort.Sort(ints);
ReadKey();
}
我会得到一个错误:
Error CS1503 Argument 1: cannot convert from 'int[]' to 'System.IComparable[]'
但是如果我们检查 Int32 的元数据,我们可以看到它实现了 IComparable
所以,
- 我不知道什么?
- 这是怎么回事?
- 我怎样才能更好地对任何数据进行排序?
int[]
不是 IComparable[]
- 后者是引用数组。
但是有一个简单的解决方案,可以也避免装箱。将您的方法声明更改为具有类型参数约束的通用方法:
public static void Sort<T>(IComparable<T>[] arr) where T : IComparable<T>
您可能还需要更改 Exchange
和 Less
方法 - 您还没有告诉我们那是什么样子的。但它们也可以(而且可能应该)是通用的。 Sort
的方法体此时不需要更改。
如果有人感兴趣:
public static class BubbleSort<T>
{
public static void Sort(T[] arr, Comparer<T> comparer = null)
{
Comparer<T> equaltyComparer = comparer ?? Comparer<T>.Default;
bool swap = true;
while (swap)
{
swap = false;
for (int i = 0; i < arr.Length - 1; i++)
{
if (Less(equaltyComparer, arr[i + 1], arr[i]))
{
Exchange(arr, i, i + 1);
swap = true;
}
}
}
}
private static bool Less(Comparer<T> comparer, T v, T w)
{
return comparer.Compare(v, w) < 0;
}
private static void Exchange(T[] arr, int i, int j)
{
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
在 Java 中,如果我想独立于数据类型对任何数据进行排序,我会使用 Comparable 接口,我发现我们在 C# 中有类似的接口,所以我有简单的排序算法:
public static void Sort(IComparable[] arr)
{
bool swap = true;
while (swap)
{
swap = false;
for (int i = 0; i < arr.Length - 1; i++)
{
if (Less(arr[i + 1], arr[i]))
{
Exchange(arr, i, i + 1);
swap = true;
}
}
}
}
所以我可以对任何实现 IComparable
接口的对象进行排序,但我不能对任何原始数据类型进行排序,而且据我所知,C# 没有像 int -> Integer 这样的原始数据类型的包装器类型,但是它有一些像 Int32 这样的结构实际上实现了 IComparable 接口,但由于某些原因我仍然不能使用它,例如:
static void Main(string[] args)
{
Int32[] ints = { 5, 2, 9, 0, 3};
BubbleSort.Sort(ints);
ReadKey();
}
我会得到一个错误:
Error CS1503 Argument 1: cannot convert from 'int[]' to 'System.IComparable[]'
但是如果我们检查 Int32 的元数据,我们可以看到它实现了 IComparable
所以,
- 我不知道什么?
- 这是怎么回事?
- 我怎样才能更好地对任何数据进行排序?
int[]
不是 IComparable[]
- 后者是引用数组。
但是有一个简单的解决方案,可以也避免装箱。将您的方法声明更改为具有类型参数约束的通用方法:
public static void Sort<T>(IComparable<T>[] arr) where T : IComparable<T>
您可能还需要更改 Exchange
和 Less
方法 - 您还没有告诉我们那是什么样子的。但它们也可以(而且可能应该)是通用的。 Sort
的方法体此时不需要更改。
如果有人感兴趣:
public static class BubbleSort<T>
{
public static void Sort(T[] arr, Comparer<T> comparer = null)
{
Comparer<T> equaltyComparer = comparer ?? Comparer<T>.Default;
bool swap = true;
while (swap)
{
swap = false;
for (int i = 0; i < arr.Length - 1; i++)
{
if (Less(equaltyComparer, arr[i + 1], arr[i]))
{
Exchange(arr, i, i + 1);
swap = true;
}
}
}
}
private static bool Less(Comparer<T> comparer, T v, T w)
{
return comparer.Compare(v, w) < 0;
}
private static void Exchange(T[] arr, int i, int j)
{
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}