C#中的集合

news/2025/3/31 12:01:53/

一、集合的概念

数组可以保存多个对象,但在某些情况下无法确定到底需要保存多少个对象,由于数组的长度不可变,因此数组将不再适用。
如何保存数目不确定的对象呢?
为了保存这些数目不确定的对象,C#中提供了一系列特殊的类,这些类可以存储任意类型的对象,并且长度可变,统称为集合

集合分类:
可分为非泛型集合泛型集合,二者均间接实现了IEnumerable接口。
(1)非泛型集合
非泛型集合位于System.Collections命名空间,它可以存储多种类型的对象,其中最常用的是ArrayList集合和Hashtable集合。
(2)泛型集合
泛型集合位于System.Collections.Generic命名空间,它只能存储同一种类型的对象,其中最常用的是List < T > 泛型集合和 Dictionary<TKey,TValue> 泛型集合。

二、非泛型集合类ArrayList

ArrayList可以容纳不同类型的对象
这些对象包括int、string、object等类型的对象
同时也提供一系列添加、删除、修改和查询元素等操作方法

int Add(object value)	|将元素添加到ArrayList集合,并且该元素可以是null,且允许重复值,返回值为所插入位置的索引值
void AddRange(ICollection c)	|将集合或者数组添加到ArrayList集合
void Clear()	|从ArrayList中移除所有元素
bool Contains(object item)	|判断某元素是否在ArrayList中
int IndexOf(object value)	|查找指定元素,并返回该元素在ArrayList中第一个匹配项的索引
void Insert(int index,object value)	|将元素插入ArrayList的指定索引处
int LastIndexOf(object value)	|查找指定元素,并返回该元素在ArrayList中最后一个匹配项的索引
void Remove(object obj)	|从ArrayList中移除指定元素的第一个匹配项
void RemoveAt(int index)|从ArrayList中移除指定索引处的元素
void Reverse()	|将整个ArrayList中元素的顺序反转
void Sort()	|对整个ArrayList中的元素进行排序,由小到大
            //创建ArrayList集合对象arrArrayList arr = new ArrayList();//使用不同方法向集合添加多个元素arr.Add(222);arr1.AddRange(new ArrayList() { "小明", "小红" });arr1.Insert(2, 'a');

集合的长度就是元素的个数,集合的容量是随集合长度变化而变化的。如果集合的长度在1-5之间。容量的值就是5。

三、foreach循环

虽然for循环可以用于遍历集合中的元素,但写法上比较繁琐,foreach在遍历时无需循环条件

 foreach (var item in collection)
{执行语句;
}
item变量用于存储每次遍历的元素(默认情况下item为var类型),in为关键字,collection是被遍历的集合。

foreach循环的次数是由元素的个数决定的,每一次循环时,foreach中都通过变量将当前循环中的元素记住,从而将集合中的元素遍历输出。

可以说foreach循环是专门用于遍历数组和集合的循环语句。

但注意,foreach循环只能对遍历到的元素进行读操作,且之能单向遍历,也就是一个元素在整个foreach循环内只能被访问一次。

Hashtable集合——非泛型集合类

在ArrayList集合中查找某个元素时,是从索引位置为0的元素开始逐一进行比对的,这样的查询效率很低,为此C#提供了一个Hashtable集合,该集合又被称为键值对集合。

void Add(object key,object value)	将带有指定键和值的元素添加到Hashtable中
void Clear()	从Hashtable中移除所有元素
bool Contains(object key)	判断Hashtable中是否包含指定的键
bool ContainsValue(object value)	判断Hashtable是否包含指定的值
void Remove(object key)	从Hashtable中移除带有指定键的元素

在Hashtable集合中的键和值的默认类型都是object,因此可以向键和值中添加任意类型的对象。在遍历Hashtable集合时,除了可以通过键来获取对应的值以外,还可以直接遍历集合的值或者集合对象

           Hashtable ht = new Hashtable();//调用Hashtable的Add()方法来添加元素ht.Add(1, "小张");ht.Add(2, "小赵");ht.Add(3, "小钱");//使用foreach语句来循环遍历集合中的值foreach (object value in ht.Values){Console.WriteLine("当前遍历到的值为:" + value);}Console.WriteLine();//使用foreach语句来循环遍历集合对象本身foreach (DictionaryEntry dicEn in ht){Console.Write(dicEn.Key + ":" + dicEn.Value + "\n");}Console.ReadKey();在遍历集合对象本身时,集合对象是DictionaryEntry类型,通过该类型的对象dicEn既可以获得键,也可以获得值。

List泛型集合

ArrayList集合与Hashtable集合可以存储多种类型的元素,由于集合中的元素类型不一致,在很多情况下,使用foreach循环获取集合中的元素时,需要对它们进行强制类型转换,这种操作大大降低了程序的执行效率。

C#中提出了泛型集合的概念,泛型集合相当于与集合制定了某个限制条件,这个条件使集合中只能存储一种类型的元素。

List< T > 是一种常用的泛型集合,T值某种数据类型,如int、string等,该集合不仅具备ArrayList集合的功能,而且还可以保证List< T >集合只能添加同类型元素,不会出现类型转换的问题。

除此以外,List< T >泛型集合不仅具有ArrayList集合的方法,而且还具有一些特有方法,如Max()、Min()、Sum()方法等

 List<int> list = new List<int>(new int[] { 1, 2, 3, 4, 5, 6 });
//获取集合中的最大值
int max = list.Max();
//获取集合中的最小值
int min = list.Min();
//获取集中元素的总和
int sum = list.Sum();

Dictionary<Tkey,TValue>泛型集合

Hashtable集合中的键与值在默认情况下都是object类型,这使得用户在取值时不可避免的遇到类型转换的问题,因此C#提供了Dictionary<Tkey,TValue>泛型集合,该集合中的键和值都只能是一种类型。

Dictionary<int, string> dic = new Dictionary<int, string>();//通过遍历集合中的键获取对应的值foreach (int key in dic.Keys)//通过遍历键值对的方式来获取键与值
foreach (KeyValuePair<int, string> kv in dic)

Dictionary<Tkey, TValue >集合的键值对类型为KeyValuePair<int,string> ,通过该类型的对象就可以获取集合中的键和值。

自定义泛型

在程序开发中,如果List< T > 泛型集合和Dictionary<Tkey,TValue>泛型集合都不能满足实际需求,还可以自定义泛型。自定义泛型可以根据用户的不同需求,灵活的设计属性和方法。
语法格式如下:
[修饰符] class类名<类型占位符>
{
程序代码
}

自定义泛型与普通类的语法格式相似,唯一的区别就是多了一个类型占位符。类型占位符通常用T来表示,可以自行修改,但要遵循变量的命名规范。

  static void Main(string[] args){//创建自定义泛型对象myClassMyClass<string> myClass = new MyClass<string>();//调用Add()方法添加一个元素myClass.Add("小小");Console.WriteLine("自定义泛型中的元素:" + myClass.Get());Console.ReadKey();}}//自定义泛型MyClass<T>class MyClass<T>{T myElement;  //定义一个T类型字段public void Add(T elem)  //创建Add()方法,指定参数类型为T{this.myElement = elem;}public T Get()  //创建Get()方法,指定返回类型为T{return this.myElement;}
}

首先在定义MyClass< T >类中,设置类型占位符为T。在Main()方法中实例化对象myClass时,通过< string >将T指定为string类型。


http://www.ppmy.cn/news/1285930.html

相关文章

ubuntu 安装apisix -亲测可用

官方未提供在ubuntu系统中安装apisix的方式&#xff0c;似乎只能通过源码方式安装&#xff0c;但是并不推荐&#xff0c;非常容易失败&#xff0c; 具体操作方式如下&#xff1a; ubuntu和Debian其实类似的&#xff0c;可使用DEB方式安装&#xff0c;如下截图 注意&#xff1…

2023年03月16日_ACM会议的一个观点总结_编程将会被终结

文章目录 威尔士的背景1 - 写代码是脏活1.1 - 计算机科学注定失败 2 - 未来的软件开发团队 最近呢在美国计算机协会 也就是ACM的一个虚拟会议上 前哈佛大学计算机教授 谷歌工程主管 马特威尔士(Matt Welsh)表示 ChatGPT和Github Copilot 预示着编程终结的开始 他断言生成…

前端性能优化 将资源放到 linux 服务器上 提升访问效率

我们先远端连接服务器 然后服务器终端输入 mkdir 目录路径建出一个新的文件路径 回到我们自己的电脑 然后 在要缓存到服务器的文件目录下打开终端 输入 scp -r ./xidis.hdr 用户名 如果没设置用户名就是root服务器公网IP:/root/xhdr例如 scp -r ./xidis.hdr root1.113.266…

处理go中clientv3连接etcd包异常

目录 1、创建任意项目 2、出现异常 3、处理异常 1、创建任意项目 go mod init go-test 项目代码内容: package main//go.etcd.io/etcd/clientv3重点处理这个包 import ("context""fmt""go.etcd.io/etcd/clientv3""log""ti…

obs video-io.c

video_frame_init 讲解 /* messy code alarm video_frame_init 函数用于初始化视频帧。它接受一个指向 struct video_frame 结构体的指针 frame&#xff0c; 视频格式 format&#xff0c;以及宽度 width 和高度 height。该函数根据视频格式的不同&#xff0c;计算出每个视频帧…

计算机网络——计算大题(七)

前言&#xff1a; 最近也是在准备计算机考试&#xff0c;我们的考试形式是上机考试&#xff0c;所以可能有些计算题是会给提供思路的&#xff0c;前面已经对本学期的计算机网络知识有了一个简单的认识与了解&#xff0c;现在我们就来对计算大题进行一个学习吧&#xff0c;这里的…

第一章 前端开发基础html

第一章&#xff1a;前端开发基础&#xff1a;html 第二章&#xff1a;前端开发基础&#xff1a;CSS 第三章&#xff1a;前端开发基础&#xff1a;JavaScript 第四章&#xff1a;前端开发基础&#xff1a;jQuery 第五章&#xff1a;前端UI框架 Layui 文章目录 网页的组成介绍语言…

Swift学习笔记第二节:数组类型

1、代码 import Foundationlet arr1 [1, 2, 3, 4, 5, 6] let arr2 ["a", "b", "c", "d", "e", "f"] let arr3 [true, false, true] let arr4: Array<Int> [1, 2, 3] let arr5: [Int] [1, 2, 3] let a…