聊聊学习List<T>搜索与排序的心得

来源:互联网 发布:python抓BING图片 编辑:程序博客网 时间:2024/06/15 04:21



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方法

未完待续···

第一次写博文,不好的地方还望大家批评指教,谢谢大家

0 0
原创粉丝点击