C#集合之列表
  .NET Framework为动态列表List提供泛型类List<T>。这个类实现了IList,ICollection,IEnumerable,IList<T>,ICollection<T>,IEnumerable<T>接口。
1.创建列表
	  创建一个赛车手类,下面的例子会用到:
public class Racer : IComparable<Racer>, IFormattable
{
public int Id { get; private set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Country { get; set; }
public int Wins { get; set; } public Racer(int id, string firstName, string lastName, string country)
: this(id, firstName, lastName, country, wins: )
{
}
public Racer(int id, string firstName, string lastName, string country, int wins)
{
this.Id = id;
this.FirstName = firstName;
this.LastName = lastName;
this.Country = country;
this.Wins = wins;
} public override string ToString()
{
return String.Format("{0} {1}", FirstName, LastName);
} public string ToString(string format, IFormatProvider formatProvider)
{
if (format == null) format = "N";
switch (format.ToUpper())
{
case null:
case "N": // name
return ToString();
case "F": // first name
return FirstName;
case "L": // last name
return LastName;
case "W": // Wins
return String.Format("{0}, Wins: {1}", ToString(), Wins);
case "C": // Country
return String.Format("{0}, Country: {1}", ToString(), Country);
case "A": // All
return String.Format("{0}, {1} Wins: {2}", ToString(), Country, Wins);
default:
throw new FormatException(String.Format(formatProvider,
"Format {0} is not supported", format));
}
} public string ToString(string format)
{
return ToString(format, null);
} public int CompareTo(Racer other)
{
if (other == null) return -;
int compare = string.Compare(this.LastName, other.LastName);
if (compare == )
return string.Compare(this.FirstName, other.FirstName);
return compare;
}
}
  调用默认的构造函数,就可以创建列表对象。在List<T>中,必须为声明为列表的值指定类型:
		  var intList = new List<int>();
		  var racers  =new List<Racer>();
	  使用默认的构造函数创建一个空列表。元素添加到列表中后,列表的容量就会扩大为可接纳4个元素。如果添加到第五个元素,列表的大小就会重新设置为包含8个元素。如果8个元素还不够,列表的大小就会重新设置为包含16个元素。每次都会将列表容量重新设置为原来的2倍。
	  如果列表的容量改变了,整个集合就会重新分配到一个新的内存块中。在List<T>泛型类的实现代码中,使用了一个T类型的数组。通过重新分配内存,创建一个新数组,Array.Copy()方法将旧数组中的元素复制到新数组中。为节省时间,如果事先知道列表中的元素个数,就可以用构造函数定义其容量:
		  List<int> intList = new List<int>(10);		
	  使用Capacity属性可以获取和设置集合的容量:
		  intList.Capacity = 20;
	  集合的元素个数用Count属性读取。
  如果已经将元素添加到列表中,且不希望添加的更多的元素,就可以调用TrimExcess()方法,去除不需要的容量。但是,因为重新定位需要时间,所以如果元素的个数超过了容量的90%,该方法就什么也不做。
		  intList.TrimExcess();
  还可以使用集合初始值给集合赋值:
		  var intList = new List<int>(){1,2};
	  集合初始值并没有反映在已编译的程序集的IL代码中,编译器会把集合初始值变成对初始值列表中的每一项调用Add()方法。
2.添加元素
	  使用Add()方法可以给列表添加元素:
		  intList.Add(1);
		  intList.Add(2);
  使用AddRange()方法,可以一次给集合添加多个元素。因为AddRange()方法的参数是IEnumerable<T>类型的对象,所以可以传递一个数组:
		  intList.AddRange(
			    new Int[]{1,2}
		  );
	  如果在实例化列表时知道集合的元素个数,就亦可以将实现IEnumerable<T>类型的对象传递给类的构造函数,类似AddRange()方法:
		  var intList = new List<int>(
			    new Int[]{1,2}
		  );
3.插入元素
	  使用Insert()方法可以在指定位置插入元素:
		  intList.Insert(3,4);
	  方法InsertRange()可以插入大量的元素。
		  racers.InsertRange(3, new Racer[] {
                   new Racer(12, "Jochen", "Rindt", "Austria", 6),
                   new Racer(22, "Ayrton", "Senna", "Brazil", 41) });
4.访问元素
	  实现了IList和IList<T>接口的所有类都提供了一个索引器,可以使用索引器来访问元素:
		  int i =  intList[0;]
	  String类也可以通过索引访问字符:
			  string s = "sdas";
              char c = s[0];
  因为List<T>集合类实现了IEnumerable接口,所以也可以使用foreach(http://www.cnblogs.com/afei-24/p/6738155.html)语句遍历集合中的元素:
		  foreach(int i in intList)
		  {
			    //..
		  }
	  除了使用foreach语句之外,List<T>类还提供了ForEach()方法,该方法用Action<T>参数声明:
		  public void ForEach(Action<T> action);
	  .NEt实现ForEach()方法的代码如下:
		  public class List<T>:ILIst<T>
		  {
			    private T[] items;
//...
    public void ForEach(Action<T> action)
			    {
				      if(action==null) throw new ArgumentNullException("action");
      foreach(T item in items)
				      {
					        action(item);
				      }
			    }
		  }
  实例:
		  racers.ForEach(
			    r => 
				    {
					      Console.WriteLine(r.ToString())
				    }
			  );
	  这里使用了lambda表达式(http://www.cnblogs.com/afei-24/p/6795233.html)。
5.删除元素
	  删除元素时,可以利用索引,也可以传递要删除的元素:
		  var graham = new Racer(7, "Graham", "Hill", "UK", 14);
          var emerson = new Racer(13, "Emerson", "Fittipaldi", "Brazil", 14);
          var mario = new Racer(16, "Mario", "Andretti", "USA", 12);
		  var racers = new List<Racer>(20) { graham, emerson, mario };
		  racers.RemoveAt(3);
          racers.Remove(graham);
按索引删除比较快,因为必须在集合中搜索要删除的元素。Remove方法先在集合中搜索,用IndexOf方法获取元素的索引,再使用该索引删除元素。IndexOf方法先检查元素类型是否实现了IEquatable<T>接口。如果是,就调用这个接口的Equals()方法,确定集合中的元素是否等于传递给Equals()方法的元素。如果没有实现这个接口,就使用Object类的Equals()方法比较这些元素。Object类的Equals()方法默认实现代码对值类型进行按位比较,对引用类型只比较其引用。
  RemoveRange()方法可以从集合中删除许多元素。它的第一个参数指定了开始删除的元素索引,第二个参数指定了要删除的元素个数:
		  int index = 3;
          int count = 5;
          racers.RemoveRange(index,count);
	  要删除集合中的所有元素,可以使用ICollection<T>接口定义的Clear()方法:
		  racers.Clear();
	  RemoveAll()方法删除有指定特性的所以元素。这个方法使用Predicate<T>类型的参数定义。下面将介绍Predicate<T>类型。
6.搜索
	  获得要查找的元素的索引,或者搜索元素的本身。可以使用的方法有IndexOf(),LastIndexOf(),FindIndex(),FindLastIndex(),Find(),FindLast().
	  如果只检查元素是否存在,可以使用Exists()方法。
  IndexOf()方法需要将一个对象作为参数,如果在集合中找到该元素,这个方法就返回该元素的索引。如果没有找到就返回—1.IndexOf方法使用IEquatable<T>接口来比较元素。
	  使用IndexOf()方法,还可以指定不需要搜索整个集合,指定从哪个元素开始搜索以及搜索几个元素。
  除了使用IndexOf()方法搜索指定元素之外,还可以搜索有某个特性的元素,该特性可以用FindIndex(),FindLastIndex(),Find(),FindLast()方法来定义,这些方法需要一个Predicate<T>类型的参数:
		  如:
		  public int FindIndex(Predicate<T> match);
	  Predicate<T>类型是一个委托:public delegate bool Predicate<T>(T obj);
	  其用法和Foreach()方法的Action委托类似。如果Predicate<T>委托返回true,就表示有一个匹配元素。如果返回false,表示没找到,继续搜素。
	  FindIndex(),FindLastIndex()方法返回找到的匹配元素的一个索引;Find(),FindLast()返回这个匹配的元素。
  如果要获得与Predicate<T>匹配的所有项而不是一项,可以使用FindAll()方法。FindAll()方法的用法一样。FindAll()方法找到第一项后不会停止,而是继续迭代集合中的每一项:
		  List<Racer> l =  racers.FindAll(r => r.Wins > 20);
7.排序
	  List<T>类可以使用Sort()方法对集合中的元素排序。Sort()方法使用快排算法排序。
	  Sort()方法有多个重载的方法。可以传递泛型委托Comparison<T>和泛型接口IComparer<T>,以及一个范围值和泛型接口IComparer<T>:
		  public void List<T>.Sort();
		  public void List<T>.Sort(Comparison<T>);
		  public void List<T>.Sort(IComparer<T>);
		  public void List<T>.Sort(Int32,Int32,IComparer<T>);
	  只有集合中的元素实现了IComparable接口,才能使用不带参数的Sort()方法。
使用public void List<T>.Sort(IComparer<T>); 需要定义一个实现了IComparer<T>接口的类,调用Sort(IComparer<T>)方法时会调用实现了IComparer<T>接口的类中的Compare方法:
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 && y == null) return ;
if (x == null) return -;
if (y == null) return ; int result;
switch (compareType)
{
case CompareType.FirstName:
return string.Compare(x.FirstName, y.FirstName);
case CompareType.LastName:
return string.Compare(x.LastName, y.LastName);
case CompareType.Country:
result = string.Compare(x.Country, y.Country);
if (result == )
return string.Compare(x.LastName, y.LastName);
else
return result;
case CompareType.Wins:
return x.Wins.CompareTo(y.Wins);
default:
throw new ArgumentException("Invalid Compare Type");
}
}
}
    客户端代码:
		    racers.Sort(new RacerComparer(RacerComparer.CompareType.Country));
  使用public void List<T>.Sort(Comparison<T>); 需要一个Comparison<T>委托。Comparison<T>委托:public delagate int Comparsion<T>(int x,int y);
	    客户端代码:
		    racers.Sort((r1,r2) => r2.Wins.CompareTo(r1.Wins));
使用Reverse()方法,可以逆转整个集合的顺序。
8.类型转换
	  使用List<T>类的ConvertAll<TOutput>()方法,可以把所以类型的集合转换位另一种类型。ConvertAll<TOutput>()方法使用Converte委托,Converte委托:public sealed delegate TOutput Converter<TInput,TOutput>(TInput from);
//定义一个Person类
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.FiastName+" " + r.LastName)
			  );
9.只读集合
	  创建集合后,它们就是可读写的。但是,在填充集合后,可以使用AsReadOnly()方法创建只读集合。
		  List<Racer> racers2 =racers.AsReadOnly();
C#集合之列表的更多相关文章
- Java 集合 散列表hash table
		Java 集合 散列表hash table @author ixenos 摘要:hash table用链表数组实现.解决散列表的冲突:开放地址法 和 链地址法(冲突链表方式) hash table 是 ... 
- redis有序集合性能 列表、集合、有序集合
		https://www.cnblogs.com/pirlo21/p/7120935.html 1.1 列表 列表(list)类型是用来存储多个字符串,元素从左到右组成一个有序的集合.列表中的每个字符串 ... 
- 2--Python入门--Python数据集合类型--列表
		在基础数据类型的基础上,Python有6中数据集合的类型: 列表list,最常用的数据类型,以[]为标识 元组tuple,和list很相似,但是不能二次赋值,用()标识 集合set,和list类似,但 ... 
- redis底层数据结构--简单动态字符串 链表  字典 跳跃表 整数集合 压缩列表
		1.动态字符串 redis中使用c语言的字符床存储字面量,默认字符串存储采用自己构建的简单动态字符串SDS(symple dynamic string) redis包含字符串的键值对都是用SDS实现的 ... 
- python基础知识-集合,列表,元组间的相互装换
		在python中列表,元祖,集合间可以进行相互转化, def main(): set1={'hello','good','banana','zoo','Python','hello'} print(l ... 
- C#泛型集合之——列表
		列表基础 1.列表概述:列表与哈希集合不同之处在于,它的元素可以重复.(更接近逻辑上的数组,而哈希集合更接近于数学上的集合) 2.创建及初始化: (1)List<类型> 列表名 =new ... 
- pyhton数据类型:字典、集合、列表、元组
		基本常识 元组 列表 字典 集合 初始化 tuple=(1,2,3,4) list=[1,2,3,4] dic={'a':12,'b':34} set={1,2,3,4} 元素索引 tuple[0] ... 
- 【redis】redis底层数据结构原理--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表等
		redis有五种数据类型string.list.hash.set.zset(字符串.哈希.列表.集合.有序集合)并且自实现了简单动态字符串.双端链表.字典.压缩列表.整数集合.跳跃表等数据结构.red ... 
- python使用一个集合代替列表
		"""说明:对于一个指定的序列,如果需要获得一个只包含该序列中不重复的序列时,使用以下算法:"""seq=['a','a','b','c', ... 
随机推荐
- mac环境下安装xampp
			首先下载XAMPP,然后配置虚拟域名hosts,再配置Apache服务, 配置Apache服务 1.打开/Applications/XAMPP/xamppfiles/etc/httpd.conf文件, ... 
- C++移位运算符详解
			移位运算符包括左移"<<"和右移">>" 左移运算符<<: 1.无符号 语法格式:需要移位的数字<<移位的次数n ... 
- java学习笔记----数据类型,变量,常量
			一.数据类型 1.基本类型(8种,又称内置数据类型).6种数字类型(byte,short,int,long,float,double),一种字符型(char),一种布尔类型(boolean). byt ... 
- 【前端童鞋看过来!】给大家分享网盘里前端相关书籍,主要是和网络通信(HTTP/TCP/IP)及javascript相关的
			百度云链接:https://pan.baidu.com/s/1kUPdf5H(无密码) 截图: <HTTP权威指南> [豆瓣书评]:此书第一部分是HTTP的概略,如果你没有时间,通读第一部 ... 
- UT源代码123
			(3)设计佣金问题的程序 commission方法是用来计算销售佣金的需求,手机配件的销售商,手机配件有耳机(headphone).手机壳(Mobile phone shell).手机贴膜(Cellp ... 
- 为什么使用 Containjs 模块化管理工具效率高?
			为什么使用 Containjs 模块化管理工具效率高? 要说明这个首先得说明一下,Containjs 的模块加载原理. 第一步,首先使用异步加载(ajax)在 js 目录下的 app.js 入口模块( ... 
- 苹果App删除 AppStore应用删除指南
			最近做IOS应用上传时,想改一下SUK或者Bundle ID ,发现改不了,只能删除. 但是删除却没有找到删除按钮,百度半天不给力,不过后来多亏一位群里的兄弟给找个链接,终于解决 今天就给他记录下来, ... 
- MyBatis使用statementType="STATEMENT"
			statementType="STATEMENT"是使用非预编译,现在我需要动态传人表名和字段名,所以需要用STATEMENT,使用之后所有变量取值都要改成${xxxx},而不是# ... 
- [SinGuLaRiTy] 树形存储结构阶段性测试
			[SinGuLaRiTy-1011] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. G2019级信息奥赛专项训练 题目 程序名 时间 内存 ... 
- Android 瘦身之道 ---- so文件
			Android 瘦身之道 ---- so文件 [TOC] 1. 前言 目前Android 瘦身只有几个方面可以入手,因为apk的结构就已经固定了. res 目录下的资源文件.(通常是压缩图片,比如 矢 ... 
