Array类:提供创建、操作、搜索和排序数组的方法,因而在公共语言运行库中用作所有数组的基类。
- 只有系统和编译器能够从 Array 类显式派生,用户不能派生与此类
- 实现了 System.Collections.Generic .IList <T >、 System.Collections.Generic .ICollection <T > 和 System.Collections.Generic.IEnumerable <T > 泛型接口
1.数组的GetType方法;
int[] h=new int[10]; h.GetType()====== System.Int32[]
2. Array.IsArray 属性
typeof(Array).IsArray FALSE
typeof(h.GetType().IsArray) true
3.数组的复制 同类型或者不同类型的标准数组之间copy自动转换(拆箱,装箱)
1)Array .ConstrainedCopy 复制没成功,则目标数组不变
public static void ConstrainedCopy(
Array sourceArray,
int sourceIndex,
Array destinationArray,
int destinationIndex,
int length
)2)Array .Copy 方法
将一个 Array 的一部分元素复制到另一个 Array 中,并根据需要执行类型强制转换和装箱。
Copy(Array, Array, Int32/Int64) 将元数组从第一个索引开始,指定长度复制到目标数组
Copy(Array, Int32/Int64, Array, Int32/Int64, Int32/Int64) 从指定的源索引开始,指定长度,复制到目标数组中以目标索引为起始位置的地方。
3)Array派生类的CopyTo
public void CopyTo(
Array array,
int index
)int[] myArray={1,2,3,4,5,6,7,8,9,10};myArray.CopyTo(deArray, 0); //1,2,3,4,5,..,9,10 将源数组的所有元素复制到目标数组指定起始的位置。目标数组要有足够大的空间。
4.数组的清除 Array.Clear
静态方法 Clear ,Array.Clear(),并不是真正的删除值。
引用类型变为null,bool类型变为false,其余为0
5.查找值 Array.Exists,TrueForAll,Find,FindLast,FindAll
Predicate<T>委托 – _
public static bool Exists<T>(
T[] array,
Predicate<T> match
)Predicate <T > 是对方法的委托,如果传递给它的对象与委托中定义的条件匹配,则该方法返回 true。 array 的元素被逐个传递给 Predicate <T >,找到一个匹配项时处理就会停止。
表示定义一组条件并确定指定对象是否符合这些条件的方法。
public delegate bool Predicate<T>(
T obj
)说明:在 C# 和 Visual Basic 中,不必显式创建 Predicate<string> 委托(在 Visual Basic 中为 Predicate(Of String))。这些语言会通过上下文推知正确的委托,并自动创建委托。
Array.TrueForAll,Exists
Find,FindLast,FindAll
6.调整数组大小
public static void Resize<T>(
ref T[] array,
int newSize
)
新长度大于旧长度,则其余都为数组类型的默认值
新长度小,则将新数组复制满,其余元素忽略
相等,则不做任何操作。
7. 数组排序sort 默认提供的是不稳定排序(相同大小的元素位置可能会改变)
1)基元类型数组或者集合的默认排序
先来说说NET 托管的基类型,有byte,sbyte,int,uint,short,ushort,long,ulong,float,double,char,bool,object,string,decimal。如果数组是这些类型的,那么可以直接使用 数组.sort()方法,因为基元类型默认都实现了Icomparable<T>接口中的CompareTo(T t1,T t2)方法
例: 整形数组a包括了 9,8,7,6,5,….,0的10个值,使用Array.sort(a) 排序后就变成了0,1,2,….9,可见默认的排序方法是从小到达排序的
static void Main(string[] args){Array a = Array.CreateInstance(typeof(int), 10);for(int i=9;i>=0;i--)a.SetValue(9-i, i);foreach (int i in a){Console.WriteLine(i);}Array.Sort(a);Console.WriteLine("排序后的数组为");foreach (int i in a){Console.WriteLine(i);}Console.ReadLine();}
2)不想使用默认的排序规则,使用自定义的排序规则
查看msdn帮助中Array.sort方法发现有2种基本的自定义规则。一个是参数为Icomparer<T>,另一个是Comparison<(Of <(T>)>) 一个委托方法 public delegate int xx(T x,Ty)
- 实现Icomparer<T>接口中的 compare方法
例:将一个整形的数组 按照从大到小的顺序排列。还是针对上面的例子中数组a,因为上面的数组a经过默认排序后变成从小到大,现自定义规则让其变成从大到小排序.
public interface IComparer<in T>
{
// 摘要:
// 比较两个对象并返回一个值,指示一个对象是小于、等于还是大于另一个对象。
//
// 参数:
// x:
// 要比较的第一个对象。
//
// y:
// 要比较的第二个对象。
//
// 返回结果:
// 一个带符号整数,它指示 x 与 y 的相对值,如下表所示。值含义小于零x 小于 y。零x 等于 y。大于零x 大于 y。
int Compare(T x, T y);
}
自定义规则的代码:
public class ReverseComparer : IComparer<int>
{
public int Compare(int x, int y)
{
return y.CompareTo(x); // y小于x,返回负数
}
}
调用排序规则
ReverseComparer c=new ReverseComparer();
Array.Sort(a, c);
Console.WriteLine("排序后的数组为"); ///打印出9,8,7,6,5
Comparison<(Of <(T>)>) 就是一个委托方法 public delegate int xx(T x,Ty)
使用委托参数,实现自定义排序规则
public int customerCompare(int x, int y){if (x > y){return 1;}else if (x == y){return 0;}else{return -1;}}
调用:
public delegate int Comparison<T>( T x, T y )
public class ReverseComparer //这没实现Icomparer接口compare方法
{
//从小到大排列
public int customerCompare(int x, int y)
{
if (x > y)
{
return 1;
}
else if (x == y)
{
return 0;
}
else
{
return -1;
}
}
}
ReverseComparer c=new ReverseComparer();
Array.Sort(a, c.customerCompare);
Console.WriteLine("排序后的数组为");
3)自定义类型,实现sort
要想实现类型集合可以sort方法,则类型必须实现Icomparable接口的CompareTo方法,一旦实现了CompareTo方法只要集合调用了sort()方法就直接返回默认的排序(因为归根到底都是基于类型,所以如果最终是数值类型,则还是按照从小到大排序)。
public interface IComparable
{
int CompareTo(object obj);
}
自定义类型Person,实现默认排序 按照person id从小到大排序
public class person:IComparable<person>{public int id;public string name;//默认唯一方法public int CompareTo(person p){if (this.id > p.id){return 1;}else if (this.id == p.id){return 0;}else{return -1;}}}
数组persons实现排序
public class persons : List<person>{public List<person> l;public persons(){l = new List<person>();}}
数组初始化数据
List<person> l = new List<person>();l.Add(new person { id = 44, name = "name44" });l.Add(new person { id = 1, name = "name1" });l.Add(new person { id = 99, name = "name99" });Console.WriteLine("Persons 排序前的数据为");foreach (person p in l){Console.WriteLine(p.id + "-" + p.name);}Console.WriteLine("Persons 排序后的数据为");l.Sort();foreach (person p in l){Console.WriteLine(p.id + "-" + p.name);}Console.ReadLine();
默认将按照id大小排序,从小到大……………………………………………………
4)自定义类型实现默认排序之外的其他排序
和基于类型一样有2种方法。一是定义个class实现Icomparer<T>接口中comparer方法.另外一个就是委托。参照上面基元类型的其他排序规则
5)匿名函数之其他排序规则
如果一个类型里有4个属性,都是基元类型,如下
public class user:IComparable<user>
{
public int id { get; set; }
public string name { get; set; }
public int age { get; set; }
public int mobile { get; set; }
}
例如:在业务1时候,需要按照id排序;在业务2的时候需要按照name排序;在业务3的时候需要按照age排序;业务4的时候需要按照mobile排序
首先想到的是可以自定义类实现comparer方法或者委托方法。对于类型user来说,系统中可能排序有8种可能,id 大小排序2种,name排序2种,age排序2种,mobile排序2种。
对于实现comparer接口来说,要自定义8个类实现Icomparable<T>接口的comparer方法,对于委托方法Comparison<(Of <(T>)>) 要实现8个函数。
此时可以使用匿名函数,在排序的时候生成排序规则
按照姓名排序:persons.sort(delegate(person a, person b) { return a.name.CompareTo(b.name); })
按照id排序:persons.sort(delegate(person a, person b) { return a.id.CompareTo(b.id); })
总结
Icomparable<T> 接口 public int CompareTo(object)方法,实现了此方法就可以默认实现sort方法
Icomparer<T>接口的 public int Compare(T a,Tb)方法 里面可以调用a.CompareTo(b),是一个排序方法
Comparison<(Of <(T>)>) 就是一个委托方法 public delegate int xx(T x,Ty)
要想实现比较必须实现Icomparable<t>,基元类型都实现了此方法。 自定义类若想实现比较,要实现此接口中的方法(如果自定义类没实现这个接口,那么这个此类型的数组将不能使用sort方法),当然也可以在自定义类型中再创建一个 compare方法,实现另一种排序规则。 CompareTo 是默认排序规则。
对于基元数据类型的数组,默认的sort方法就是从小到大排序(不稳定的快速排序方法,相等的元素位置不保证不变),如果自定义排序规则,则实现Icomparer<T>中的 Compare方法
另外其他一些:
Sort<(Of <(T>)>)(array<T>[]()[], Int32, Int32) 对数组的某个范围内进行排序, 参数:数组,起始索引,长度
Sort<(Of <(TKey, TValue>)>)(array<TKey>[]()[], array<TValue>[]()[], IComparer<(Of <(TKey>)>))基于第一个 Array 中的关键字,使用指定的 IComparer<(Of <(T>)>) 泛型接口,对两个 Array 对象(一个包含关键字,另一个包含对应的项)进行排序。

浙公网安备 33010602011771号