1.搜索
List<T>中与搜索相关的方法有Find、FindAll、FindLast等。
这些搜索的方法原理上都是一样的咱们就着重看一下Find。
对于Find方法
MSDN上给的解释是:搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List<T> 中的第一个匹配元素。
前半句我就看蒙了,啥叫谓词(语文不好,后来查了下其实就是谓语的意思,主语谓语宾语的那个谓语)?
啥叫谓词所定义的条件?Find的参数Predicate<T> match 又是个啥,以前没见过这样的啊。
原来这个Predicate<T> match是一个bool类型的委托(其实就是一个方法),当执行Find方法的时候,当前List<T>里的所有元素
被逐个传递给Predicate<T>委托,与委托中定于的条件进行比对。从第一个元素开始,到最后一个元素结束。没有找到匹配项时
Predicate<T>委托就会返回False然后将下一个元素传入到委托中,当找到匹配项时,委托就会返回True然后停止向委托中传送
List<T>中的元素。
这样一来问题就清晰多了,想要通过Find来搜索只需要我们自己定义一个bool类型的方法,然后绑定给Predicate<T>就行了
例如我们建一个Book的类,该类只有三个属性(ID,Author,Title),然后创建一些该类的对象放到一个名为Books的列表中。
然后自定义一个方法FindTitle2来搜索Title属性值为"Title2"的对象并显示该对象的Author属性。
示例代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 聊聊列表的Find方法 { class Program { private static List<Book> Books = new List<Book>(); static void Main(string[] args) { Books.Add(new Book("0", "小明", "Title0")); Books.Add(new Book("1", "小黄", "Title1")); Books.Add(new Book("2", "小刚", "Title2")); Books.Add(new Book("3", "小二", "Title3")); foreach (Book bk in Books ) { Console.WriteLine("ID:{0} Author :{1} Title:{2}:", bk.ID ,bk.Author,bk.Title ); } Book xBook = Books.Find(FindTitle2); Console.WriteLine("\n执行Find:\n"); Console.WriteLine("The Author of \"Title2\" is {0}\n", xBook.Author); Console.WriteLine("按任意键退出程序"); Console.ReadKey(); } //定义作为参数的方法 //该方法的作用就是接收传入的对象并比对是否满足条件,满足就返回True //该方法是用户根据查找的内容自定的 private static bool FindTitle2(Book bk) { if (bk.Title == "Title2") { return true; } { return false; } } } } public class Book { public string ID { get; set; } public string Author { get; set; } public string Title { get; set; } public Book(string id, string author, string title) { this.ID = id; this.Author = author; this.Title = title; } }
运行结果:
到这,Find方法理解起来就容易的多了。其他的例如FindAll等其实和Find用法都是一样的这里就不再一一介绍了。
总结:要搞明白Find的用法关键在于两点。第一点就是Find方法执行的步骤:当执行Find方法的时候,当前List<T>里的所有元素
被逐个传递给Predicate<T>委托,与委托中定于的条件进行比对。从第一个元素开始,到最后一个元素结束。没有找到匹配项时
Predicate<T>委托就会返回False然后将下一个元素传入到委托中,当找到匹配项时,委托就会返回True然后停止向委托中传送
List<T>中的元素。
第二点就是要搞明白Predicate<T>这个委托。明白了这两点搜索就容易理解了。
说完了搜索,咱们再聊聊排序。
2016-09-08更新:
使用Lambda表达式:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 聊聊列表的Find方法 { class Program { private static List<Book> Books = new List<Book>(); static void Main(string[] args) { Books.Add(new Book("0", "小明", "Title0")); Books.Add(new Book("1", "小黄", "Title1")); Books.Add(new Book("2", "小刚", "Title2")); Books.Add(new Book("3", "小二", "Title3")); foreach (Book bk in Books) { Console.WriteLine("ID:{0} Author :{1} Title:{2}:", bk.ID, bk.Author, bk.Title); } //使用Lambda表达式 Book xBook = Books.Find(bk=> { if (bk.Title == "Title2") { return true; } { return false; } }); Console.WriteLine("\n使用Lambda表达式"); Console.WriteLine("执行Find:\n"); Console.WriteLine("The Author of \"Title2\" is {0}\n", xBook.Author); Console.WriteLine("按任意键退出程序"); Console.ReadKey(); } } } public class Book { public string ID { get; set; } public string Author { get; set; } public string Title { get; set; } public Book(string id, string author, string title) { this.ID = id; this.Author = author; this.Title = title; } }
运行结果:
2.排序
List<T>的排序有这么几个方法:
<span style="font-size:14px;">public void List<T>.Sort(); public void List<T>.Sort(Comparision<T>); public void List<T>.Sort(ICompararer<T>); public void List<T>.Sort(Int32,Int32,ICompararer<T>);</span>
2.1不带参数的Sort方法
<span style="font-size:14px;">public void List<T>.Sort();</span>
对于不带参数的Sort方法用一句话来书就是:
只要一个类实现了Icomparable<T>接口,那么把该类的实例(对象)放到列表中,列表就能用不带参数的Sort方法排序所有元素
什么意思呢,举个例子吧,看代码:
<span style="font-size:14px;">using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 聊聊列表的排序 { class Program { private static List<string> stringBooks = new List<string>(); static void Main(string[] args) { stringBooks.Add("天龙八部"); stringBooks.Add("神雕侠侣"); stringBooks.Add("倚天屠龙记"); stringBooks.Add("射雕英雄传"); stringBooks.Add("天龙八部"); foreach (string bk in stringBooks) { Console.WriteLine("未排序: {0}", bk); } stringBooks.Sort(); foreach (string bk in stringBooks) { Console.WriteLine("排 序 之 后: {0}", bk); } Console.ReadKey(); } } }</span>运行结果:
在这个示例中列表中的元素类型是string,而string类是已经实现了Icomparable<T>接口的,所以我们能直接用Sort方法就可以实现排序。
所以说只要一个类实现了Icomparable<T>接口,那么把该类的实例(对象)放到列表中,列表就能用不带参数的Sort方法排序所有元素
string类默认就实现了Icomparable<T>接口,那么对于自定义的类呢?这就需要我们自己实现Icomparable<T>接口了。
Icomparable<T>接口只有一个方法:
<span style="font-size:14px;">int CompareTo ( T other )</span>该方法返回一个int类型的值,指示要比较的对象的相对顺序。返回值的含义如下:
所以,对于自定义的类,就要这样:
<span style="font-size:14px;">using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 聊聊列表的排序 { class Program { private static List<Book > Books = new List<Book>(); static void Main(string[] args) { Books.Add(new Book ("天龙八部")); Books.Add(new Book("神雕侠侣")); Books.Add(new Book("倚天屠龙记")); Books.Add(new Book("射雕英雄传")); Books.Add(new Book("天龙八部")); foreach (Book bk in Books) { Console.WriteLine("未排序: {0}", bk.Title ); } Books.Sort(); foreach (Book bk in Books) { Console.WriteLine("排 序 之 后 : {0}", bk.Title ); } Console.ReadKey(); } } public class Book:IComparable<Book>//继承<span style="font-family:SimSun;">IComparable<T>接口</span> { public string Title { get; set; } public Book(string title) { this.Title = title; } //实现CompareTo方法 public int CompareTo(Book other) { return this.Title.CompareTo(other.Title); } } }</span>运行结果:
总结一下:对于不带参数的Sort方法,我们不用关心它到底是用什么办法排序的,只需要在我们的类中实现Icomparable<T>接口
就能排序。如何实现Icomparable<T>接口呢?先继承,然后再在类中实现Icomparable<T>接口唯一的方法CompareTo。
在上边的Book类中实现CompareTo方法其实也是利用了string类的CompareTo方法,这样一来就简单多了,如果是对于其他数据类型或者自定类型,实现CompareTo方法就压麻烦的多
有兴趣的可以仔细考究下这方面的知识。这里我就不深入的写了。
还有一点需要提一下,上边的例子中Book只有一个属性,假设Book拥有多个属性,也是可以按照他的每个属性进行排序的。在《C#高级编程》中有如何实现的方式。这里就不贴代码了。
2.2带参数的Sort方法
未完待续···
第一次写博文,不好的地方还望大家批评指教,谢谢大家