数组的长度声明后就是固定的,且都是存的同一种类型的数据。
集合的长度是不固定的(主要特征),可以存不同类型的元素;但泛型集合必须是同一种类型的集合
集合内部的原理用的还是数组,都是依赖于数组的,内部存数据都是存到了数组中。
using System.Collections;
(非泛型集合)using System.Collections.Generic;
(泛型集合)AraylList、List<T>
Hashtable
、Dictionary<K,V>
Stack
、Stack<T>
(LIFO)Last In First OutQueue
、Queue<T>
(FIFO)First In First OutSortedlList
、SortedList<K, V>
(占用内存更少,可以通过索引访词)SortedDictionary<K,V>
(占用内存更多,没有索引,但插入、删除元素的速度比SortedList
快)Set
集合:无序、不重复。HashSet<T>
,可以将HashSet类视为不包含值的Dictionary
集合。与List<T>
类似。SortedSet<T>
(.net4.0支持,有序无重复集合)LinkedList<T>
,增删速度快。ArrayList
、Hashtable
、List<T>
、 Dictionary<K,V>
:
System.Colections
ArayList
可变长度数组,使用类似于数组
Capacity
(集合中以容纳元素的个数,翻信增长);Count
(集合中实际存放的元素的个数。)Add(10)
AddRange(ICollection c)
Remove()
RemoveAt()
Clear()
Contains()
ToArray()
Sort()
排序 Reverse()
//反转Hashtable
键值对的集合,类似于字典,Hashtable
在查找元素的时候,速度很快。
Add(object key, object value)
;hash["key"]
;hash["key"]="修改"
;ContainsKey(key)
;Remove("key")
;hash.Keys
;hasth.Values/Dictionary Entry
;using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.Collections; namespace 集合 { static class Program { static void Main() { ArrayList arrayList = new ArrayList();// 注意提示有几个重载函数。 //向集合中增加元素 arrayList.Add(10); // 传的参数为 object,什么类型都可以。 arrayList.Add("10"); arrayList.Add("张三丰"); Person gj = new Person() { Name = "郭靖", }; arrayList.Add(gj); // 添加对象也可以。 // ▼ Count 表示集合中的元素实际个数 Console.WriteLine("集合中存在的元素个数{0}。", arrayList.Count); // ▼ Capacity 容量,可以理解:容量有 100,实际上可以只放 1 个元素。 Console.WriteLine("集合现在的容量{0}", arrayList.Capacity); Console.WriteLine("==========传接口类型=========="); // ICollection 接口, ArrayList 自己也可以往里传,数组也可以。所有集合,所有数组都可以传。 // 实现了 ICollection 的类都可以 arrayList.Add(new int[] { 1, 3, 5, 7, 9 }); // 集合获取元素 Console.WriteLine(arrayList[0]);// 用索引器访问 Console.WriteLine(arrayList[3]); Console.WriteLine("==========for 循环遍历集合=========="); // ▼ for 循环遍历集合 for(int i = 0; i < arrayList.Count; i++) { // C# 所有集合长度都是 Count,数组都是 Length。 Console.WriteLine(arrayList[i]); } // 向指定位置插入一个元素 Console.WriteLine("==========向指定位置插入一个元素=========="); arrayList.Insert(0, "洪七公");// 索引为 0 的位置中插入,以前的依次向后移动 for (int i = 0; i < arrayList.Count; i++) { // C# 所有集合长度都是 Count,数组都是 Length。 Console.WriteLine(arrayList[i]); } // 也可以插一堆的元素 Console.WriteLine("==========向指定位置插入一堆元素=========="); arrayList.InsertRange(3, new string[]{ "a", "good", "moring"}); for (int i = 0; i < arrayList.Count; i++) { // C# 所有集合长度都是 Count,数组都是 Length。 Console.WriteLine(arrayList[i]); } // 删除元素 可以根据 IDE 的提示参数去理解函数的含义 //arrayList.Remove; //arrayList.RemoveAt;// 根据索引来删除 //arrayList.RemoveRange;// 删除一段,从第几个开始删除到第几个元素,这个比较好理解。 Console.WriteLine("===========删除结果是:============="); Console.WriteLine(arrayList.Count); for (int i = 0; i < arrayList.Count; i ++) { arrayList.RemoveAt(i); } Console.WriteLine(arrayList.Count);// 可见,删一个就移动重组一下。 Console.WriteLine("===========清除ArrayList============="); arrayList.Clear(); Console.WriteLine("集合中存在的元素个数{0}。", arrayList.Count); // foreach 是只读循环 Console.WriteLine("===========根据对象来删除============="); // ▼ 根据对象来删除 Person p1 = new Person() { Name = "雪山飞狐", Age = 100, Email = "nb@sina.com.cn" }; arrayList.Add(p1); arrayList.Add(99); arrayList.Add("黄蓉"); Person p2 = new Person() { Name = "雪山飞狐", Age = 100, Email = "nb@sina.com.cn" }; arrayList.Add(p2); Console.WriteLine("集合中存在的元素个数{0}。", arrayList.Count); arrayList.Remove(99); Person p3 = new Person(); p3.Name = "雪山飞狐"; p3.Age = 100; p3.Email = "nb@sina.com.cn"; Console.WriteLine("集合中存在的元素个数{0}。", arrayList.Count); arrayList.Remove(p3);// 这个对象没有添加,也就没有删除,但也没报错 Console.WriteLine("集合中存在的元素个数{0}。", arrayList.Count); // 如果这样就能删掉 p3 = p1; arrayList.Remove(p3);// 这个对象没有添加,也就没有删除,但也没报错 Console.WriteLine("集合中存在的元素个数{0}。", arrayList.Count); // ▲ 这样能删除 string name = new string(new char[] { '黄', '蓉'}); arrayList.Remove(name); // 删除掉了“黄蓉” Console.WriteLine("集合中存在的元素个数{0}。", arrayList.Count); // 总结: // Remove 并不是按照是不是对象的地址来删除的,而是判断是不是相等来删除的。 Console.WriteLine(arrayList.Contains(99)); // 判断是否包含这个元素 } } public class Person { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } } }
输出:
集合中存在的元素个数4。 集合现在的容量4 ==========传接口类型========== 10 集合.Person ==========for 循环遍历集合========== 10 10 张三丰 集合.Person System.Int32[] ==========向指定位置插入一个元素========== 洪七公 10 10 张三丰 集合.Person System.Int32[] ==========向指定位置插入一堆元素========== 洪七公 10 10 a good moring 张三丰 集合.Person System.Int32[] ===========删除结果是:============= 9 4 ===========清除ArrayList============= 集合中存在的元素个数0。 ===========根据对象来删除============= 集合中存在的元素个数4。 集合中存在的元素个数3。 集合中存在的元素个数3。 集合中存在的元素个数2。 集合中存在的元素个数1。 False 请按任意键继续. . .
要想任意类型实现ArrayList Sort() 排序,需要实现 IComparable 这个接口。
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.Collections; namespace ArrayList排序等 { static class Program { static void Main() { #region ArrayList 的 sort 方法 ArrayList arr = new ArrayList(new int[] { 1, 3, 26, 9, 10 }); Console.WriteLine("==========升序========"); arr.Sort();// 注意有三个重载 for (int i = 0; i < arr.Count; i++) { Console.WriteLine(arr[i]); } // 默认的是升序排序,从小到大.没有降序排序但可以 Reverse Console.WriteLine("==========降序========"); arr.Reverse(); // 先升序,再反转就成降序了 for (int i = 0; i < arr.Count; i++) { Console.WriteLine(arr[i]); } /*字符串排序*/ ArrayList arrList = new ArrayList(new string[] { "hl", "xzl", "yzk", "fxh","ksjd","" ,"zaz"}); arrList.Sort(); Console.WriteLine("==========字符串排序========"); for (int i = 0; i < arrList.Count; i++) { Console.WriteLine(arrList[i]); } // ▲ 字符串排序,按第一个字母 ASCII 码大小排序。第一个字母比完,第二个字母比,依次比较。 // 升序比较。 Console.WriteLine("==========对象排序========"); ArrayList arrObj = new ArrayList(); Person p1 = new Person() { Name = "hjk", Age = 100, Email = "hhh@andyvj.com" }; Person p2 = new Person() { Name = "gdss", Age = 90, Email = "sd@andyvj.com" }; Person p3 = new Person() { Name = "cbv", Age = 80, Email = "ge@andyvj.com" }; Person p4 = new Person() { Name = "rtsssy", Age = 70, Email = "ghkj@andyvj.com" }; arrObj.Add(p1); arrObj.Add(p2); arrObj.Add(p3); arrObj.Add(p4); Console.WriteLine("元素个数:" + arrObj.Count); arrObj.Sort(); // 对象不能直接按这个排,因为不知道按什么排 // 对象需要继承 IComparable 接口实现 CompareTo方法 for (int i = 0; i < arrObj.Count; i++) { Console.WriteLine(((Person)arrObj[i]).Name); // 装箱成对象了,要强制转一下。 } // 想要 Sort 排序,数据类型必须是实现过 IComparable 这个接口的 // 所以 Person 对象想要排序,就必须要实现 IComparable 这个接口 #endregion } public class Person: IComparable { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } // ▼ IComparable 接口实现 CompareTo方法 public int CompareTo(object obj) { Person p = obj as Person; if (p != null) { /* return this.Age - p.Age; // 升序降序在这里改下相减的前后顺序 // ▲ 按照年龄,大 > 0,等 = 0, 小 < 0 */ return this.Name.Length - p.Name.Length; // 按名字的长度排序 } return 0; } // 总结:要想任意类型实现ArrayList Sort() 排序,需要实现 IComparable 这个接口。 } } }
输出:
==========升序======== 1 3 9 10 26 ==========降序======== 26 10 9 3 1 ==========字符串排序======== fxh hl ksjd xzl yzk zaz ==========对象排序======== 元素个数:4 hjk cbv gdss rtsssy 请按任意键继续. . .
总结:如果要升序再写一个类实现 IComparer,如果按年龄再写一个类实现IComparer,依次… 有多少个情况。
就写多少个比较的类就行了,不用去改源代码。
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.Collections; namespace Arralist随意排序 { static class Program { static void Main() { Console.WriteLine("==========对象排序========"); ArrayList arrObj = new ArrayList(); Person p1 = new Person() { Name = "hjk", Age = 100, Email = "hhh@andyvj.com" }; Person p2 = new Person() { Name = "gdss", Age = 90, Email = "sd@andyvj.com" }; Person p3 = new Person() { Name = "cbv", Age = 800, Email = "ge@andyvj.com" }; Person p4 = new Person() { Name = "rtsssy", Age = 70, Email = "ghkj@andyvj.com" }; arrObj.Add(p1); arrObj.Add(p2); arrObj.Add(p3); arrObj.Add(p4); Console.WriteLine("元素个数:" + arrObj.Count); // ▼ 直接调用Sort()方法是使用person类型实现了IComparab1e接口的默认方式来排序 // arrObj.Sort(); for (int i = 0; i < arrObj.Count; i++) { Console.WriteLine(((Person)arrObj[i]).Age); } // 看 Sort() 函数的重载提示,有 IComparer 接口类型参数,一个比较器。 // 所以有一个实现了接口的类就可以了。 arrObj.Sort(new PersonSortByNameLengthAsc()); Console.WriteLine("==========姓名长短排序后========"); for (int i = 0; i < arrObj.Count; i++) { Console.WriteLine(((Person)arrObj[i]).Name); } } } public class Person: IComparable { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } public int CompareTo(object obj) { Person p = obj as Person; if (p != null) { return this.Age - p.Age; } return 0; } } // ▼ 这个类就是一个比较器 public class PersonSortByNameLengthAsc : IComparer { public int Compare(object x, object y) { Person p1 = x as Person; Person p2 = y as Person; if (x != null && y != null) { return p1.Name.Length - p2.Name.Length; } else { throw new Exception("null 无法比较"); } } } // 总结:如果要升序再写一个类实现 IComparer,如果按年龄再写一个类实现IComparer,依次… 有多少个情况 // 就写多少个比较的类就行了,不用去改源代码了。 }
输出:
==========对象排序======== 元素个数:4 100 90 800 70 ==========姓名长短排序后======== hjk cbv gdss rtsssy 请按任意键继续. . .
参考:
1.C# .Net基础加强第六天 // B站视频教程地址,来自:传智播客