目录
一.什么是泛型
过数据类型的替代参数编写类或方法的规范。当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型。
二:如何创建泛型集合
泛型集合属于集合的一类,同样是在Systeam.Collections.Generic命名空间下:
创建语法:List<T> ListOfT = new List<T>();
其中的"T"就是所要使用的类型,既可以是简单类型,如string、int,也可以是用户自定义类型。
如下:
using System.Collections.Generic;
using UnityEngine;
public class HsjList : MonoBehaviour
{
void Start()
{
//创建Person对象
Person p1 = new Person("张三", 30);
Person p2 = new Person("李四", 20);
Person p3 = new Person("王五", 50);
//创建类型为Person的对象集合
List<Person> persons = new List<Person>();
//将Person对象放入集合
persons.Add(p1);
persons.Add(p2);
persons.Add(p3);
//输出第2个人的姓名
Debug.Log(persons[1].Name);
}
}
class Person
{
private string _name; //姓名
private int _age; //年龄
public Person(string Name, int Age)
{
this._name = Name;
this._age = Age;
}
public string Name
{
get { return _name; }
}
public int Age
{
get { return _age; }
}
}
三:List<T> 泛型集合的排序
排序基于比较,要排序,首先要比较。比如有两个数1、2,要对他们排序,首先就要比较这两个数,根据比较结果来排序。如果要比较的是对象,情况就要复杂一点,比如对Person对象进行比较,则既可以按姓名进行比较,也可以按年龄进行比较,这就需要确定比较规则。一个对象可以有多个比较规则,但只能有一个默认规则,默认规则放在定义该对象的类中。
1.默认的排序比对规则
默认比较规则在CompareTo方法中定义,该方法属于IComparable<T>泛型接口。请看下面代码:
class Person: IComparable<Person>
{
private string _name; //姓名
private int _age; //年龄
public Person(string Name, int Age)
{
this._name = Name;
this._age = Age;
}
public string Name
{
get { return _name; }
}
public int Age
{
get { return _age; }
}
//一个对象可以有多个比较规则,但只能有一个默认规则,默认规则放在定义该对象的类中
public int CompareTo(Person other)
{
return this.Age - other.Age;
}
}
CompareTo方法的参数为要与之进行比较的另一个同类型对象,返回值为int类型,如果返回值大于0,表示第一个对象大于第二个对象,如果返回值小于0,表示第一个对象小于第二个对象,如果返回0,则两个对象相等。定义好默认比较规则后,就可以通过不带参数的Sort方法对集合进行排序:
persons.Sort();
foreach (var item in persons)
{
Debug.Log(item.Name);
}
2.自定义排序比对规则
实际使用中,经常需要对集合按照多种不同规则进行排序,这就需要定义其他比较规则,可以在Compare方法中定义,该方法属于IComparer<T>泛型接口,请看下面的代码
//定义新的比较器继承IComparer接口实现Compare方法
class NameComparer : IComparer<Person>
{
//存放排序器实例
public static NameComparer Default = new NameComparer();
public int Compare(Person x, Person y)
{
return Comparer.Default.Compare(x.Name, y.Name);
}
}
Compare方法的参数为要进行比较的两个同类型对象,返回值为int类型,返回值处理规则与CompareTo方法相同。其中的Comparer.Default返回一个内置的Comparer对象,用于比较两个同类型对象。
persons.Sort(NameComparer.Default);
foreach (var item in persons)
{
Debug.Log(item.Name);
}
3.利用委托来进行集合排序
还可以通过委托来进行集合排序,首先要定义一个供委托调用的方法,用于存放比较规则,可以用静态方法。这个方法可以定义自己想要的比对规则,很方便自定义多种。请看下面的代码:
class PersonComparison
{
//通过名字排序
public static int Name(Person p1, Person p2)
{
return Comparer.Default.Compare(p1.Name, p2.Name);
}
//通过年级排序
public static int Age(Person p1, Person p2)
{
return Comparer.Default.Compare(p1.Age, p2.Age);
}
}
方法的参数为要进行比较的两个同类型对象,返回值为int类型,返回值处理规则与CompareTo方法相同。然后通过内置的泛型委托System.Comparison<T>对集合进行排序:
Comparison<Person> nameComparison = new Comparison<Person>(PersonComparison.Name);
persons.Sort(nameComparison);
foreach (var item in persons)
{
Debug.Log(item.Name);
}
4.泛型集合的扩展
考虑到单个类可以提供的功能是有限的,很自然会想到对List<T>类进行扩展,泛型类也是类,因此可以通过继承来进行扩展。
如果要得到集合中所有人的姓名,中间以逗号隔开,那该怎么处理?请看下面的代码:
//定义Person的集合类
class Persons : List<Person>
{
public string GetAllName()
{
if (this.Count < 0) return "";
string allName = "";
foreach (var item in this)
{
allName += item.Name;
}
return allName;
}
}
然后通过创建集合类的对象调用内部方法:
Persons people = new Persons();
people.Add(p1);
people.Add(p2);
people.Add(p3);
Debug.Log(people.GetAllName());
四.List的属性和方法以及用法
1.声明
a:List<T> mList = new List<T>();
List<Person> person1 = new List<Person>();
b: List<T> testList =new List<T> (IEnumerable<T> collection);以一个集合作为参数创建List
Person[] people = { new Person("张三", 30), new Person("李四", 20), new Person("王五", 50) };
List<Person> persons = new List<Person>(people);
2.添加元素
a:添加单个 List. Add(T item)
List<Person> person1 = new List<Person>();
person1.Add(new Person("王麻子",10));
b:添加一组元素List. AddRange(IEnumerable<T> collection)
Person[] people = { new Person("张三", 30), new Person("李四", 20), new Person("王五", 50) };
List<Person> person1 = new List<Person>();
person1.AddRange(people);
c:在指定位置插入元素 Insert(int index, T item);
person1.Insert(1,new Person("王麻子",10));
3.遍历泛型集合
foreach (var item in persons)
{
Debug.Log(item.Name);
}
for (int i = 0; i < persons.Count; i++)
{
Debug.Log(persons[i].Name);
}
4.删除元素
a:删除一个元素,语法:List. Remove(T item)
for (int i = 0; i < persons.Count; i++)
{
if (persons[i].Name=="张三")
{
persons.Remove(persons[i]);
}
Debug.Log(persons[i].Name);
}
b:删除指定下标的元素,语法:List. RemoveAt(int index);
persons.RemoveAt(2);
c:删除指定下标后数count个元素,语法:List. RemoveRange(int index, int count);
persons.RemoveRange(1, 2);
5. Contains
判断某个元素是否在该List里面,语法:List. Contains(T item) 返回值为:true/false
if (persons.Contains())
6.排序sort()参考上面细节
//通过匿名函数自定义排序规则
personList.Sort((a, b) =>
{
if (a.Age > b.Age) return 1;
else if (a.Age == b.Age) return 0;
else return -1;
});
personList.Sort((a, b) =>
{
return a.Age.CompareTo(b.Age);
});
7.Reverse翻转
List元素顺序翻转,语法: List. Reverse () 可以与List. Sort ()配合使用,达到想要的效果
personList. Reverse();
8.清空Clear
语法:List. Clear ()
personList.Clear ()
9.元素数目Count
语法: List. Count () 返回int值
personList. Count ()
10.List.FindAll()
检索与指定谓词所定义的条件相匹配的所有元素 ,
语法:public List<T> FindAll(Predicate<T> match);
List<Person> p = personList.FindAll((a) =>a.Name =="张三");
11.List.Find()
搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中的第一个匹配元素。
语法:public T Find(Predicate<T> match);一下两种方式
Person p = personList.Find((a)=>a.Name == "李四");
Person p = personList.Find(FindItem);
private bool FindItem(Person obj)
{
if (obj.Name =="张三")
{
return true;
}
return false;
}
12.List.FindLast()
搜索与指定位置所定义的条件相匹配的元素,并返回整个 List 中的最后一个匹配元素。
语法:public T FindLast(Predicate<T> match);用法与List.Find相同。
13.List.TrueForAll()
确定是否 List 中的每个元素都与指定的谓词所定义的条件相匹配。
语法:public bool TrueForAll(Predicate<T> match);委托给拉姆达表达式:
bool b = personList.TrueForAll((a)=>a.Age==10);
14.List.Where()
检索与指定谓词所定义的条件相匹配的所有元素。跟List.FindAll方法类似。
foreach (var item in personList.Where((a) => a.Age == 10))
{
}
15.List.RemoveAll()
移除与指定的谓词所定义的条件相匹配的所有元素。
语法: public int RemoveAll(Predicate<T> match);
int a = personList.RemoveAll((a)=>a.Age==10);