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

简介: 1.搜索 List<T>中与搜索相关的方法有Find、FindAll、FindLast等。 这些搜索的方法原理上都是一样的咱们就着重看一下Find。 对于Find方法 MSDN上给的解释是:搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List<T> 中的第一个匹配元素。 前半句我就看蒙了,啥叫谓词(语文不好,后来查了下其实就是谓语的意思,主



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

未完待续···

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

目录
相关文章
|
7月前
|
Java
【Java基础】Java8 使用 stream().sorted()对List集合进行排序
【Java基础】Java8 使用 stream().sorted()对List集合进行排序
215 0
|
8月前
|
存储 JavaScript 前端开发
数据结构之List | 让我们一块来学习数据结构
数据结构之List | 让我们一块来学习数据结构
92 0
|
4天前
|
搜索推荐 算法 C++
list容器-排序案例讲解
list容器-排序案例讲解
10 0
|
4天前
|
算法 C++ 容器
list容器-反转和排序讲解39
list容器-反转和排序讲解39
22 0
|
4天前
|
存储 NoSQL Java
【Redis】1、学习 Redis 的五大基本数据类型【String、Hash、List、Set、SortedSet】
【Redis】1、学习 Redis 的五大基本数据类型【String、Hash、List、Set、SortedSet】
60 0
|
4天前
|
Java
Java对list集合元素进行排序的几种方式
Java对list集合元素进行排序的几种方式
27 0
|
4天前
|
存储 Java 索引
从零开始学习 Java:简单易懂的入门指南之Collection集合及list集合(二十一)
从零开始学习 Java:简单易懂的入门指南之Collection集合及list集合(二十一)
|
9月前
|
人工智能 Java API
一文学会List函数排序操作,20秒即可完成!
假设有一个用户管理系统,其中包含两个用户列表:一个是从数据库中获取的原始用户列表,另一个是从外部API获取的新用户列表。在这种情况下,用Java函数来实现将新用户列表中的数据合并到原始用户列表中的功能。
|
4天前
|
存储 C语言 C++
【C++学习手札】模拟实现list
【C++学习手札】模拟实现list
|
4天前
|
存储 算法 搜索推荐
C++_list快速学习入门(中英文结合)
C++_list快速学习入门(中英文结合)
20 1