C#编程(四十八)----------列表
C#中的List
C#中deList怎么样?List<T>类是ArrayList类的泛型等效类,该类使用大小可按需动态增长的数组实现List<T>泛型接口.
泛型的好处:它为使用C#语言编写面向对象程序增加了极大的效力和灵活性,不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转化,所以性能得到提高.
性能注意事项:再决定使用List<T>还是使用ArrayList类(两者具有类似的功能)时,记住IList<T>类在大多数情况下执行得更好并且是类型安全的.如果对IList<T>类的类型T使用引用类型,则两个类的行为是完全相同的,但是如果对类型T使用值类型,则需要考虑实现和装箱问题.
C#List的基础常用方法:
一.声明:
1. List<T> list=new List<T>():
T为列表中元素类型,现在以string类型作为例子:
List<string> list=new List<string>():
2.List<T> list = new List<T>(IEnumerable<T> collection);
以一个集合作为参数创建List:
string[] temArr = { "Ha", "Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", "Locu" };
List<string> testList = new List<string>(temArr);
二.添加元素:
1. List.Add( Titem)添加一个元素
例如:testList.Add(“hahaha”);
2. List.AddRange(IEnumerable <T> collection) 添加一组元素
例: string[] temArr = { "Ha", "Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", "Locu" };
List<string> testList = new List<string>();
testList.AddRange(temArr);
3. Insert(int index ,T item) ; 在index位置添加一个元素
例:testList.Insert(1,”hello”);
三.遍历List中的元素:
案例:
string[] temArr = { "Ha", "Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", "Locu" };
List<string> testList = new List<string>();
testList.AddRange(temArr);
foreach (var item in testList)
{
Console.WriteLine(item);
}
四.删除元素:
1.List.Remove(T item)删除一个值
例:mList.Remove(“hahaha”);
2.List.RemoveAt(int index);删除下标为index 的元素
例:mList.RemoveAt(0);
3.List.RemoveRange(int index , int count);从下标index开始,删除count个元素
例:mList.RemoveRange(3,2);
五.判断某个元素是否在该List中:
List.Contains(T item) 返回true或false,很实用
例: string[] temArr = { "Ha", "Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", "Locu" };
List<string> testList = new List<string>();
testList.AddRange(temArr);
if (testList.Contains("Hunter"))
{
Console.WriteLine("There is Hunter in the list");
}
else
{
testList.Add("Hunter");
Console.WriteLine("Add Hunter successfully.");
}
六.给List里面的元素排序:
List.Sort();
例:mList.Sort();
七.给List里面元素顺序反转:
List. Reverse ()可以不List. Sort ()配合使用,达到想要的效果
例:
mList.Sort();
八、List清空:
List. Clear ()
例:
mList.Clear();
九、获得List中元素数目:
List. Count ()返回int值
例:
in tcount = mList.Count();
Console.WriteLine("The num of elements in the list: "+count);
综合案例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 集合
{
class Program
{
static void Main(string[] args)
{
//比较List<T>(泛型的)和ArrayList(非泛型的)
People p1 = new People("zhangsan", 21);
People p2 = new People("lisi", 11);
People p3 = new People("wangwu", 41);
//将People对象加到集合中
List<People> list = new List<People>(4);
list.Add(p1);
list.Add(p2);
list.Add(p3);
/*如果不指定list容量大小,默认是0,只要有元素加入时,会自动扩展到4,如果第五个元素加入时
* 就变成了8,第九个元素加入时,就变成了16
* 可以看出,容量总是成倍的增长,扩展时要重新开辟内存,这样会影响效率,如果事先知道元素个数,
* 或者可能判断个数,最好给出个大体的容量值
* 我们加入了三个元素,就设容量大小为4.注意:设为4不是说只能存放四个元素
* 而是说,如果超出四个,一样会成倍扩展,这样做是为了减小扩展带来的开销
*/
/*
* 这个方法作用是清楚多于的没有用的内存空间.例如:如果开辟大小为100
* 但是我们只用了4个,其余的不用,是不是浪费
* 本方法调用时会检查元素个数是不是占到了容量的90%以上
* 如果是,则不进行回收
*/
list.TrimExcess();
/*ArrayList方法和List<T>用法一样,不同的是,它是对象集合
* 参数是object这样会有装箱拆箱的可能
* 所以尽量使用List<>
*/
/*
* 1.初始化集合器
* C#3.0开始,提供了初始化功能,但是并没有反映到IList代码中
* 在IList中,一样也是把它转化成Add方法调用
*/
List<int> l2 = new List<int>() { 1, 2, 3, 4, 5 };
/*
* 2.添加元素AddRange()方法可以一次性添加一批对象
*/
List<People> lists = new List<People>(10);
//参数是一个必须可能迭代的对象,也可能是一个数组
list.AddRange(new People[] { new People("aladdin", 20), new People("zhao", 6) });
//构造传入批量参数,与AddRange效果一样
List<People> myList = new List<People>(new People[] { new People("aladdin", 20), new People("zhao", 6) });
/*
* 3.插入元素
* 使用Insert()方法,可以在指定位置插入元素
* 例 我们在1的位置插入,则最后变成了aladdin jacky zhao..插入意思就是,这个位我占了,
* 以前占这位的和他之后的,通通往后移一位
*/
myList.Insert(1, new People("Jacky", 22));
foreach (var p in myList)
{
Console.WriteLine(p.name);
}
/*
*4.访问元素
*ArrayList和List<T>都是提供了索引器来访问的
*/
Console.WriteLine("*********访问元素********");
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i].name);
}
//还可以使用foreach迭代器来实现
/*
* public delegate void Action<T>(T obj);用委托作为参数
*/
Console.WriteLine("********用foreach方法输出********");
myList.ForEach(param => Console.WriteLine(param.name));
/*
* 5.删除元素
* 删除元素可以使用RemoveAt()直接传入索引器值
* 将第一个元素直接删除
*/
myList.RemoveAt(0);
List<People> lists2 = new List<People>(10);
People per1 = new People("aladdin", 100);
People per2 = new People("zhao", 100);
People per3 = new People("jacky", 100);
lists2.Add(per1);
lists2.Add(per2);
lists2.Add(per3);
lists2.Remove(per3);
Console.WriteLine("***********删除后的元素*********");
foreach (var per in lists2)
{
Console.WriteLine(per.name);
}
/*
* 从结果可以看出,名称为jacky的元素被删除了
* 下面说一下Remove方法的删除过程
* 用IndexOf方法确定出对象的索引,然后按索引删除
* 在IndexOf方法内,首先检查元素是不是实现了IEquatable接口,如果是,就调用这个
* 这个接口的Equals()方法
* 如果没有实现,则掉用Object中的Equals方法比较元素(也就是地址比较)
* 以上我们删除per3,很明显是一个地址,所以被删除了
* 下面我们改装People,实现了IEquatable<People,在
* 比较方法中,始终返回false,同per3会比较失败,不会被删除
* 结果三个都在
* 如果要删除对象,最好使用索引直接删除,因为Remove方法经历了一系列过程后,最后才按索引删除!
*
* RemoveRange()方法删除一个范围
* 第一个参数:开始位置;第二个参数:个数
* lists2.RemoveRange(1,2);
* 使用foreach查看批量删除后的结果
* foreach (var per in lists2)
*{
* Console.WriteLine(per.name);
*}
*
*/
/*
* 6.搜索
* 搜索有很多方式,可以使用
* IndexOf,LastIndexOf,FindIndex,FindLastIndex,Find,FindLast
* 如果指示查看元素的存在情况,可以使用Exists()方法
* IndexOf()方法需要将一个对象做参数,如果存在,就返回本元素在集合中的索引,
* 如果找不到就返回-1,IndexOf还可以使用IEquatable接口来比较元素
*/
List<People> ls3 = new List<People>(10);
People person1 = new People("aladdin",100);
People person2 = new People("zhao",100);
People person3 = new People("jacky",100);
ls3.Add(person1);
ls3.Add(person2);
ls3.Add(person3);
//为了使用默认的地址比较,我们把People的接口暂时去掉
int index = ls3.IndexOf(person3);
Console.WriteLine("per3的索引 : "+index);
//还可以指定搜索范围 从第三个开始,范围长度为1
int index2 = ls3.IndexOf(person3, 2, 1);
Console.WriteLine(index2);
//FindIndex()方法用来搜索带有一定特性的元素
//用委托做参数 public delegate bool Predicate<T>(T obj);
int index3 = ls3.FindIndex(param => param.name.Equals(""));
Console.WriteLine(index3);//2
//FindLastIndex是从 后面查第一个出现的元素,因为我们这里没有重复元素,所以
//体现不出它只能查找一个,就停下来的效果
int index4 = ls3.FindLastIndex(p => p.name.Equals("aladdin"));
Console.WriteLine(index4);
//Find方法与FindIndex方法用于一样,不同的是,它返回的是元素本身
People ppp = ls3.Find(p => p.name.Equals("jacky"));
Console.WriteLine(ppp);
/*
* 如果要查找所有的匹配元素,而不是找到第一个就停下来,就是用FindAll()方法
* 我们查找所有年纪等于100的对象,3个都符合
*/
List<People> newList = ls3.FindAll(p => p.age == 100);
Console.WriteLine("**********查找所有**********");
foreach (var p in newList)
{
Console.WriteLine(p.name);
}
/*
* 7.排序
* List可以利用Sort方法排序,实现算符是快速排序
* 本方法有好几个重载
* public void Sort()只对元素实现了IComparable才能使用这个方法 ,如果实现了则,可以直接调用一次sort之后,就排好序了
* public void Sort(Comparison<T> comparison)我们的Person并没有实现那个接口,所以要用泛型委托当参数的方法
* public void Sort(IComparer<T>(T x , T y))泛型接口当参数 public delegate int Comparison<T>(T x, T y);
*
* public void Sort(int index ,int count ,IComparer<T> comparer) 可以指定范围
*/
List<People> ls4 = new List<People>(10);
People person4 = new People("aladdin",100);
People person5 = new People("zhao", 33);
People person6 = new People("jacky", 44);
ls4.Add(person4);
ls4.Add(person5);
ls4.Add(person6);
ls4.Sort(MyComparFunc);
Console.WriteLine("***********排序后的************");
foreach (var p in ls4)
{
Console.WriteLine(p.name+p.age);
}
Console.WriteLine("***********颠倒顺序***********");
ls4.Reverse();
foreach (var p in ls4)
{
Console.WriteLine(p.name+p.age);
}
/*
* 8.类型转换 可以将集合中的元素转换成任意类型的元素,比如,
* 我们要将集合中的People转换成为Racer对象Racer只包含名字,没有年纪
* public List<T Output>ConvertAll<TOutput>(Converter<T, TOutput> converter);
* public delegate T Output Converter<T Input, T Output>(T Input input); 委托参数
*/
List<Racer> ls5 = ls4.ConvertAll<Racer>((input) => new Racer(input.name));
Console.WriteLine("***********转换后的玩意***********");
foreach (var r in ls5)
{
Console.WriteLine(r.name);
}
/*9.只读集合
* 在创建完集合以后,肯定是可读的,如果不是,他就不能再添加新元素了
* 但是,如果是认为填充完毕,不要再做修改
* 可以使用只读集合,使用AsReadOnly方法返回ReadOnlyCollection<T>
* 类型,它与List<>操作是一样的,但是一但有修改集合的操作,就会抛出异常
* 它屏蔽了通常的Add方法
*/
IReadOnlyCollection<Racer> persss = ls5.AsReadOnly();
Console.WriteLine("输出只读集合");
foreach (var r in persss)
{
Console.WriteLine(r.name);
}
Console.ReadKey();
}
public static int MyComparFunc(People p1, People p2)
{
if (p1.age==p2.age)
{
return 0;
}
else if (p1.age > p2.age)
{
return 1;
}
else
{
return -1;
}
}
}
public class People
{
public string name;
public int age;
public People(string name, int age)
{
this.name = name;
this.age = age;
}
}
public class Racer
{
public string name;
public Racer(string name)
{
this.name = name;
}
}
}
C#中数组,ArrayList和List三者的区别
在C#中数组,ArrayList,List都能够存储一组对象,那么三者到底有何区别呢?
数组
数组在C#中最早出现的.在内存中是连续存储的,所以他的索引速度非常快,而且赋值与修改元素也很简单.
案例:
string [] s=new string [2];
//赋值
s[0]=”a”;
s[1]=”b”;
//修改
s[1]=”aa”;
但是数组存在一些不足的地方.在数组的两个数据间插入数据是很麻烦的,而且在声明数组的时候必须制定数组的长度,数组的长度过长,会造成内存浪费,过界会造成数据溢出的错误.如果在声明数组的时候我们不清楚数组的长度,就会变得很麻烦.
针对数组的这些缺点,C#中最先提供了ArrayList对象来克服这些缺点.
ArrayList
ArrayList是命名空间System.Collections下的一部分,在使用该类时必须进行引用,同时继承了IList接口,提供了数据存储和检索.ArrayList对象的大小是按照其中存储的数据来动态扩充与收缩的.所以,在声明ArrayList对象时并不需要指定它的长度.
案例:
ArrayList list1=new ArrayList();
//新增数据
list1.Add(“cde”);
list1.Add(5678);
//修改数据
list1[2]=34;
//移除数据
list1.Remove(0);
//插入数据
list1.Insert(0,”qwe”);
从上面例子看,ArrayList好像是解决了数组中的所有的缺点,为什么又会有List?
我们从上面的例子看,在List中,我们不仅插入了字符串cde,而且插入了数字5678.这样在ArrayList中插入不同类型的数据是允许的.因为ArrayList会把所有插入其中的数据当做为object类型来处理,在我们使用ArrayList处理数据时,很可能会报类型不匹配的错误,也就是ArrayList不是类型安全的.在存储或检索值类型时通常发生装箱和拆箱操作,带来很呆的性能损耗.
装箱与拆箱的概念:
简单的说:
装箱:就是将值类型的数据打包到引用类型的实例中
比如将string类型的值abc赋给object对象obj
案例:
string i=”abc”;
object obj=(object)i;
拆箱:就是从引用数据中提取值类型
比如将object对象obj的值赋给string类型的变量i :
object obj=”abc”;
string i=(string)obj;
装箱与拆箱的过程是很损耗性能的.
泛型List
因为ArrayList存在不安全类型与装箱拆箱的缺点,所以出现了泛型的概念.List类是ArrayList类的泛型等效类,他的大部分用法都与ArrayList相似,因为List类也继承IList接口.最关键的却别在于,在声明List集合时,我们同事需要为其声明List集合内数据的对象类型.
List<string>list=new List<string>();
//新增数据
list.Add(“abc”);
//修改数据
list[0]=”def”;
//移除数据
list.Remove(0);
上例中,如果我们往List集合中插入int数组123,IDE就会报错,且不能通过编译.这样就避免了前面讲的类型安全问题与拆箱的性能问题了.
总结:数组的容量是固定的,您只能一次获取或设置一个元素的值,而ArrayList或List<T>的容量可根据需要自动扩充,修改,删除或插入数据.
数组可以具有多个维度,而ArrayList或List<T>时钟只具有一个维度.但是您可以轻松创建数组列表或列表的列表.特定类型(object除外)的数组的性能优于ArrayList的性能.这是因为ArrayList的元素属于object类型;所以在存储或检索值类型时通常发生装箱和拆箱操作.不过,在不需要重新分配时(即最初的容量十分接近列表的最大容量),List<T>的性能与同类型的数组十分相近.
在决定使用List<T>还是使用ArrayList类(两者具有类似的功能)时,记住List<T>类在大多数情况下执行的更好并且是类型安全的.如果对List<T>类的类型T使用引用类型,则两个类的行为是完全相同的.但是,如果对类型T使用值类型,则需要考虑实现和装箱操作.
C#编程(四十八)----------列表的更多相关文章
- Bootstrap <基础二十八>列表组
列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ...
- NeHe OpenGL教程 第四十八课:轨迹球
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- SQL注入之Sqli-labs系列第四十七关,第四十八关,第四十九关(ORDER BY注入)
0x1 源码区别点 将id变为字符型:$sql = "SELECT * FROM users ORDER BY '$id'"; 0x2实例测试 (1)and rand相结合的方式 ...
- 《手把手教你》系列技巧篇(四十八)-java+ selenium自动化测试-判断元素是否可操作(详解教程)
1.简介 webdriver有三种判断元素状态的方法,分别是isEnabled,isSelected 和 isDisplayed,其中isSelected在前面的内容中已经简单的介绍了,isSelec ...
- 第四十八个知识点:TPM的目的和使用方法
第四十八个知识点:TPM的目的和使用方法 在检查TPM目的之前,值得去尝试理解TPM设计出来的目的是为了克服什么样的问题.真正的问题是信任.信任什么?首先内存和软件运行在电脑上.这些东西能直接的通过操 ...
- 学习ASP.NET Core Razor 编程系列十八——并发解决方案
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之十二(四十八)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...
- salesforce 零基础学习(四十八)自定义列表分页之Pagination基类封装 ※※※
我们知道,salesforce中系统标准列表页面提供了相应的分页功能,如果要使用其分页功能,可以访问http://www.cnblogs.com/zero-zyq/p/5343287.html查看相关 ...
- 读书笔记_Effective_C++_条款四十八:了解模板元编程
作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> st ...
随机推荐
- Eclipse的git插件冲突合并方法
Eclipse有一个git的插件叫EGit,用于实现本地代码和远程代码对比.合并以及提交.但是在本地代码和远程代码有冲突的时候,EGit的处理方案还是有点复杂.今天就彻底把这些步骤给理清楚,并公开让一 ...
- Ubuntu下SSH安装
step: 1.输入命令: sudo apt-get install openssh-server 2.验证sshserver是否启动了,以下两条命令均可 ps -e | grep ssh netst ...
- mysql 用init-connect+binlog实现用户操作追踪做access的ip的log记录
在MYSQL中,每个连接都会先执行init-connect,进行连接的初始化.我们可以在这里获取用户的登录名称和thread的ID值.然后配合binlog,就可以追踪到每个操作语句的操作时间,操作人等 ...
- SqlServer Case when then用法总结
SELECT d.DicName , --DevelopMode ISNULL(NULL,NULL) , --Orgid b.FullName , --Areid c.DicName , --Inve ...
- 记录一起k8s的service服务名解析灵异事件
故障现象: 基于alpine 3.7的镜像,构建的spring boot服务及eureka服务器. 在使用deployment和service文件部署到k8s集群之后, 在不同的pod内部,访问ser ...
- 【LOJ】#2509. 「AHOI / HNOI2018」排列
题解 虽然要求一个dfs序,但是不是从根开始贪心 从最小的点开始贪心,最小的点显然是父亲选了之后马上就选它 那么我们每次把最小的点和父亲合并,两个联通块之间也是如此 对于两个联通块,他们合并的顺序应该 ...
- 用python实现一个无界面的2048
转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5519453.html 以前游戏2048火的时候,正好用其他的语言编写了一个,现在学习python,正好想起来,便决定 ...
- 使用IDEA搭建spring
从前使用eclipse开发,集成jar包,现在使用maven来管理 一: 1.框架 2.pom 需要spring core与spring context. <?xml version=" ...
- 常见的网络攻击(XSS,SQL注入,CSRF)
一.XSS 二.SQL注入 三.CSRF
- 【BZOJ 4569】 4569: [Scoi2016]萌萌哒 (倍增+并查集)
4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 865 Solved: 414 Description 一个长 ...