c#之List学习笔记

来源:互联网 发布:第一会所会员账号 淘宝 编辑:程序博客网 时间:2024/06/03 14:51

List
泛型类List实现了IList,ICollection,IEnumerable,IList,ICollection和IEnumerable接口
其中
Ilist:接口用于可通过位置访问其中的元素列表,这个接口定义了一个索引器,可以在集合的指定位置插入或删除某些项(Insert()和RemoveAt()方法)。IList接口派生自ICollection接口。
ICollection:接口由泛型集合类实现。使用这个接口可以获得集合中的元素个数(Count属性),把集合复制到数组中(CopyTo()方法),还可以从集合中添加和删除元素(Add(),Remove(),Clear())
IEnumerable:如果将foreach语句用于集合,就需要IEnumerable接口。这个接口定义了方法GetEnumerator(),他返回一个实现了IEnumerator接口的枚举。

1.创建列表
例:

var intList = new List<int>();var racers = new List<Racer>();

2.列表容量以及大小
使用Capacity属性获取和设置集合的容量,也可以在初始化的时候直接设置。集合中的元素个数可以用Count属性读取。其中容量总是大于或等于元素个数。只要不把元素添加到列表中,元素个数就是0.如果已经将元素添加到列表中,且不希望添加更多的元素,可以调用TrimExcess()方法去除不需要的容量。但是因为重新定位需要时间,所以如果元素个数超过了容量的90%,TrimExcess()方法就什么也不做。
例:

List<int>intList = new List<int>(10);或者List<int>intList=new List<int>();intList.Capacity = 20;Console.WriteLine(intList.Count);intList.TrimExcess();

3.列表初始化
例:

var intList = new List<int>(){1,2};var stringList = new List<string>(){"one","two");

4.添加元素
(1).使用Add()方法可以给列表添加元素.
(2).使用List类的AddRange()方法,可以一次给集合添加多个元素。因为AddRange()方法的参数是IEnumerable类型的对象,所以也可以传递一个数组。
例:

var intList = new List<int>();intList.Add(1);var graham = new Racer(7,"Graham","Hill","UK",14);var racers = new List<Racer>(20){graham};racers.Add(new Racer(24,"Michael","Schumacher","Germany",91));racers.AddRange(new Racer[]{new Racer(14,"Niki","Lauda","Austria",25),new Racer(21,"Alain","Prost","France",51)});var racers = new List<Racer>(new Racer[]{new Racer(12,"Jochen","Rindt","Austria",6),new Racer(22,"Ayrton","Senna","Brazil",41)});

5.插入元素
(1).使用Insert()方法可以在指定位置插入元素
(2).方法InsertRange()提供了插入大量元素的功能,类似于前面的AddRange()方法。如果索引集大于集合中的元素个数,就抛出ArgumentOutOfRangeException类型的异常。
例:

racers.Insert(3,new Racer(6,"Phil","Hill","USA",3));

6.访问元素
实现了IList和IList接口的所有类都提供了一个索引器,所以可以使用索引器,方法是通过传送元素号来访问元素。第一个元素可以用索引值0来访问。指定racers[3],可以访问列表中的第4个元素。
例:

Racer r1 = racers[3];

7.遍历列表中的元素
(1)通过索引遍历
例:

for(int i  = 0; i < racers.Count; i++){    Console.WriteLine(racers[i]);}

(2)因为List集合类实现了IEnumerable接口,所以也可以使用
例:

foreach(Racer r in racers){    Console.WriteLine(r);}

(3)使用ForEach()方法:public void ForEach(Action action);
实现ForEach()方法的代码如下。ForEach()方法遍历集合中的每一项,调用作为每一项的参数传递的方法。
public class List:IList
{
private T[] items;
//…
public void ForEach(Action action)
{
if(action == null) throw new ArgumentNullException(“action”);
foreach(T item in items)
{
action(item);
}
}
例:

racers.ForEach(Console.WriteLine);racers.ForEach(r=>Console.WriteLine("{0}",r));

8.删除元素
(1).利用索引:RemoveAt()
例:
racers.RemoveAt(3);
(2)传递要删除的元素:Remove()。按索引删除比较快,因为必须在集合中搜索要删除的元素。Remove()方法先在集合中搜索,用IndexOf()方法获取元素的索引,再使用该索引删除元素。IndexOf()方法先检查元素类型是否实现了IEquatable接口。如果是,就调用这个接口的Equals()方法,确定集合中的元素是否等于传递给Equals()方法的元素。如果没有实现这个接口,就使用Object类的Equals()方法比较这些元素。Object类中Equals()方法中的默认实现代码对值类型进行按位比较,对引用类型只比较其引用。
例:

if(!racers.Remove(graham){    Console.WriteLine("object not found in collection");}

其中graham是一个对象,若graham对应的类没有重写IEquatable接口和Object.Equals方法,则不能用要删除元素的内容相同创建一个新对象,再把它传递给Remove()方法。
(3)RemoveRange()方法可以从集合中删除许多元素。它的第一个参数指定了开始删除的元素索引,第二个参数指定了要删除的元素个数。
(4)RemoveAll()方法:在搜索元素时使用Predicate参数。要删除集合中的所有元素,可以使用ICollection接口定义的Clear()方法。
例:

int index = 3;int count =5;racers.RemoveRange(index,count);

9.搜索
(1)IndexOf()方法,需要将一个对象作为参数,如果在集合中找到该元素,这个方法就返回元素的索引。如果没有找到该元素,就返回-1.IndexOf()方法使用IEquatable接口来比较元素。使用IndexOf()方法,还可以指定不需要搜索整个集合,但必须指定从哪个索引开始搜索以及比较时要迭代的元素个数。
例:

int index1 = racers.IndexOf(mario);

(2).FindIndex()方法:可以用于搜索有某个特性的元素。返回元素的索引,并可以直接获得集合中的元素。FindIndex()方法需要一个Predicate类型的参数。
public int FindIndex(Predicatematch);
其中Predicate类型是一个委托,该委托返回一个布尔值,并且需要把类型T作为参数。这个委托的用法与ForEach()方法中的Action委托类似。如果Predicate委托返回true,就表示有一个匹配元素,并且找到了相应的元素。如果它返回false,就表示没有找到元素,搜索将继续。
public delegate bool Predicate(T obj);
使用FindIndex()方法还可以指定搜索开始的索引和要遍历的元素个数。为了从集合中的最后一个元素开始向前搜索某个索引,可以使用FindLastIndex()方法。
例:

public class FindCountry{    public FindCountry(string country)    {        this.country = country;    }    private string country;    public bool FindCountryPredicate(Racer racer)    {        if(racer == null)throw new ArgumentNullException("racer");        return racer.Country == country;    }}int index2 = racers.FindIndex(new FindCountry("Finland").FindCountryPredicate);int index3 = racers.FindIndex(r=>r.Country=="Finland");

(3).Find()方法需要一个Predicate类型的参数,与FindIndex()方法类似。
例:
Racer racer = racers.Find(r=>r.FirstName==”Niki”);
(4)FindAll()方法可以获得Predicate类型匹配的所有项,而不是一项。FindAll()方法在找到第一项后,不会停止搜索,而是继续迭代集合中的每一项,并返回Predicate类型是true的所有项。
例:

List<Racer>bigWinners = racers.FindAll(r=>r.wins > 20);foreach(Racer r in bigWinners){    Console.WriteLine("{0}",r);}

10.排序
(1)Sort():使用快速排序算法,比较所有的元素,直到整个列表排好序为止。Sort()方法使用了几个重载的方法。可以传递给它的参数有泛型委托Comparison和泛型接口Icomparer,以及包含泛型接口IComparer的一个范围值。
public void List.Sort();
public void List.Sort(Comparison);其中Comparison是一个方法委托,该方法有两个T类型的参数,返回类型为int.如果参数值相等,该方法就必须返回0.如果第一个参数比第二个参数小,它就必须返回一个小于0的值,否则必须返回一个大于0的值。
public delegate int Comparison(T x,T y);
public void List.Sort(IComparer);
public void List.Sort(Int32,Int32,IComparer);
只有集合中的元素实现了IComparable接口,才能使用不带参数的Sort()方法。
例:

public class RacerComparer:IComparer<Racer>{    public enum CompareType    {        FirstName,        LastName,        Country,        Wins    }    private CompareType compareType;    public RacerComparer(CompareType compareType)    {        this.compareType = compareType;    }    public int Compare(Racer x,Racer y)    {        if(x == null)throw new ArgumentNullException("x");        if(y==null)throw new ArgumentNullException("y");        int result;        switch(compareType)        {            case CompareType.FirstName:                return x.FirstName.CompareTo(y.FirstName);            case CompareType.LastName:                return x.LastName.CompareTo(y.LastName);            case CompareType.Country:                if((result == x.Country.CompareTo(y.Country)) == 0)                    return x.LastName.CompareTo(y.LastName);                else                    return result;            case CompareType.Wins:                return x.Wins.CompareTo(y.Wins);            defaule:                throw new ArgumentException("Invalid Compare Type");        }    }}racers.Sort(new RacerComparer(RacerComparer.CompareType.Country));racers.ForEach(Console.WriteLine);racers.Sort((r1,r2)=>r2.Wins.ComPareTo(r1.Wins));

11.类型转换
(1)ConvertAll()方法,可以把所有类型的集合转换为另一种类型。ConvertAll()方法使用一个Converter委托,该委托的定义如下:
public sealed delegate TOutput Converter

[Serializable]public class Person{    private string name;    public Person(string name)    {        this.name = name;    }    public override string ToString()    {        return name;    }}List<Person> persons = racers.ConvertAll<Person>(r=>new Person(r.FirstName+" "+r.LastName));

12.只读集合
创建集合后,他们就是可读写的。但是在填充完集合后,可以创建只读集合。List集合的AsReadOnly()方法返回ReadOnlyCollection类型的对象。ReadOnlyCollection类实现的接口与List集合相同,但所有修改集合的方法和属性都抛出NotSupportedException异常。

1 0
原创粉丝点击