在学习集合之前我们需要先来了解一下集合:
集合,表示可以通过遍历每个元素来访问一组对象(特别是可使用foreach循环访问)。
集合和数组的区别:
保存的数量 | 字长 | 内存 | 遍历速度 | |
数组 | 固定 | 固定 | 占用少 | 快 |
集合 | 灵活 | 不定长 | 占用多 | 慢 |
在功能上,数组能实现的所有功能,集合都可以实现;反之集合能实现的某些功能,数组却难以实现。
数组 | 集合(List) | ||
定义的格式: | 数据类型[] 变量名; | List<数据类型>变量名; | |
赋值 | 变量名=new 数据类型[长度] 由于数据的定长,所以赋值时,必须指定长度 |
变量名=new List<数据类型> | |
初始化 | 变量名=new 数据类型[长度]{元素1,元素2,...} | 变量名=new List<数据类型>{元素1,元素2}; | |
由于集合不定长,集合可以添加,插入,删除,修改元素 | 添加元素: 变量名.add(要添加的数据) 其中添加的数据类型必须和集合定义时规定的一样 |
||
插入元素: 变量名.Insert(索引,要插入的数据) |
|||
删除元素: 变量名.RemoveAt(索引) 删除指定索引位置的元素 变量名.Remove(数据) 删除集合中与填写的数据相同的第一个匹配项 |
|||
修改数据 | 变量名.[索引]=值 | 俩个相同 | |
获取元素数量 | 变量名.Length | 变量名.Count |
数组是C#中最早出现的,虽然他的索引速度非常快,但是任然存在一些不足的地方,在数组的两个数据之间插入数据是非常麻烦的,而且在声明数据的时候必须指定数组的长度,类型等等。
针对数组的这些切点,C#提供了ArrayList对象来克服这些缺点
例子:
ArrayList list1 = new ArrayList();
//新增数据
list1.Add("cde");
list1.Add(5678);
//修改数据
list[2] = 34;
//移除数据
list.RemoveAt(0);
//插入数据
list.Insert(0, "qwe");
上面的例子来看,我们在集合中既插入了字符串类型,也插入了数值,不同的类型在ArrayList中是允许的,因为ArrayList会把所有插入其中的数据当做object类型来处理,所以是不安全的类型。
所以ArrayList在存储或检索值类型时候通常发生装箱和拆箱的操作,带来很大的消耗。
所谓转箱和拆箱就是:
装箱:将值类型的数据打包到引用类型的实例中
拆箱:从引用类型中提取值
ArrayList(非泛型集合)与List(泛型集合)
LIST 它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。
list = new List<string>();
//新增数据
list.Add(“abc”);
//修改数据
list[0] = “def”;
//移除数据
list.RemoveAt(0);
总结:
数组的容量是固定的,您只能一次获取或设置一个元素的值,而ArrayList或List<T>的容量可根据需要自动扩充、修改、删除或插入数据。
数组可以具有多个维度,而 ArrayList或 List< T> 始终只具有一个维度。
例子:
{//随机的在这个list集合中添加十个数字,不能重复,求和,求最大值,求最小值,求平均值
List<int> list = new List<int>(); //实例化,表示要在list中存放整数
Random r = new Random();
int num = 0;
while (list.Count!=10)
{
num = r.Next(100);//表示产生一个0~9之间的随机数
if (!list.Contains(num))//判断list中有没有当前的num值
{
list.Add(num);
}
list.Add(num);
}
//求最大值
Console.WriteLine("最大值:{0}", list.Max());
Console.WriteLine("最小值:{0}", list.Min());
Console.WriteLine("综合:{0}",list.Sum() );
Console.WriteLine("平均值:{0}", list.Average());
List 的其他方法:
List.clear //移除所有的元素
List.contains()//比较集合中是否有该元素
List.indexof()//当前位置的索引
其实还有一个和集合是非常相像的----字典:
实例化字典的格式:
Dictionary<string, string> dic = new Dictionary<string, string>();
//Dictionary<键值,value>
dic.Add("老苏", "凤姐");
dic.Add("老牛", "芙蓉姐姐");
Dictionary<int, string> myIdc = new Dictionary<int, string>();
myIdc.Add(1, "haha");
想要遍历整个字典:
foreach (string item in dic.Keys)
{
Console.WriteLine("key---{0},vlaue---{1}", item, dic[item]);
//item 表示键值 dic.[item] ---- 相当于 value
}
Console.ReadKey();
哈希表:
//哈希表,以键值的形式存储,key----键 value---值;
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add("老苏","001");
ht.Add("小马", 003);
ht.Add(new Person("小洋", '男', 18), 005);
可以存储任何类型的数据,是存储但的数据不能重复
键值对均为 object 类型
特点:无序的
遍历哈希表的方法:
foreach(var item in ht.keys)//代表单个的key
{
console.writeline(ht[item])// item可以改变名
}
//ht[item] 键值对应的value
一个小例子:
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ArrayList al = new ArrayList();
//哈希表 以键值对的形式存值 key -----键 value-----值
//无序的
ht.Add("老苏", "1001");
ht.Add("小马",1002);
ht.Add(1003,"老牛");
ht.Add(new Person("小杨",'男',18),1005);
ht.Add("小赵","老马");
ht.Remove(1003);
Console.WriteLine("{0}-----{1}","老苏",ht["老苏"]);
Console.WriteLine("===========================");
foreach (object str in ht.Values)
{
//Console.WriteLine("key{0},-------value{1}",str,ht[str]);
//如果我们把 ht.keys 转换为 ht.values ,
//那么str就不是索引 而是值 可以直接显示出来
Console.WriteLine(str);
}
Console.WriteLine("添加成功了");
Console.ReadKey();