C#.Net基础加强第六天:集合之ArrayList

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

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

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

集合的命名空间

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

常用集合

  • 类似数组集合:AraylList、List<T>
  • “键值对”集合(“哈希表”集合):HashtableDictionary<K,V>
  • “堆栈”集合:StackStack<T>(LIFO)Last In First Out
  • “队列”集合:QueueQueue<T>(FIFO)First In First Out
  • “可排序键值对“集合:(插入、检索没有“哈希表”集合高效)
    • SortedlListSortedList<K, V>(占用内存更少,可以通过索引访词)
    • SortedDictionary<K,V>(占用内存更多,没有索引,但插入、删除元素的速度比SortedList快)
  • Set集合:无序、不重复。HashSet<T>,可以将HashSet类视为不包含值的Dictionary集合。与List<T>类似。SortedSet<T>(.net4.0支持,有序无重复集合)
  • “双向链表”集合:LinkedList<T>,增删速度快。

增删改查遍历

ArrayListHashtableList<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;
    • 键值对集合中的”键”,绝对不能重复。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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;
}
}
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
集合中存在的元素个数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 这个接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
==========升序========
1
3
9
10
26
==========降序========
26
10
9
3
1
==========字符串排序========

fxh
hl
ksjd
xzl
yzk
zaz
==========对象排序========
元素个数:4
hjk
cbv
gdss
rtsssy
请按任意键继续. . .

ArrayList 任何情况排序

总结:如果要升序再写一个类实现 IComparer,如果按年龄再写一个类实现IComparer,依次… 有多少个情况。

就写多少个比较的类就行了,不用去改源代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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,依次… 有多少个情况
// 就写多少个比较的类就行了,不用去改源代码了。
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
==========对象排序========
元素个数:4
100
90
800
70
==========姓名长短排序后========
hjk
cbv
gdss
rtsssy
请按任意键继续. . .




参考:
1.link-01 // B站视频教程地址,来自:传智播客

感谢支持!