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使用值類型,則需要考慮實現和裝箱操作.
轉載于:https://www.cnblogs.com/FinleyJiang/p/7602656.html
總結
以上是生活随笔為你收集整理的C#编程(四十八)----------列表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解 GCD
- 下一篇: c# char unsigned_dll