0
点赞
收藏
分享

微信扫一扫

C# 集合之 ArrayList

是她丫 2022-09-08 阅读 219

数组的长度声明后就是固定的,且都是存的同一种类型的数据。

集合的长度是不固定的(主要特征),可以存不同类型的元素;但泛型集合必须是同一种类型的集合。

集合内部的原理用的还是数组,都是依赖于数组的,内部存数据都是存到了数组中。

集合的命名空间

  • ​using System.Collections;​​(非泛型集合)
  • ​using System.Collections.Generic;​​(泛型集合)

常用集合

  • 类似数组集合:​​AraylList、List<T>​
  • “键值对”集合(“哈希表”集合):​​Hashtable​​​、​​Dictionary<K,V>​
  • “堆栈”集合:​​Stack​​​、​​Stack<T>​​(LIFO)Last In First Out
  • “队列”集合:​​Queue​​​、​​Queue<T>​​(FIFO)First In First Out
  • “可排序键值对“集合:(插入、检索没有“哈希表”集合高效)
  • ​SortedlList​​​、​​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 排序等

要想任意类型实现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
请按任意键继续. . .

ArrayList 任何情况排序

总结:如果要升序再写一个类实现 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站视频教程地址,来自:传智播客



举报

相关推荐

0 条评论