【C#基础】数组和集合

枚举

枚举类型(也称为枚举)为定义一组可以赋给变量的命名整数常量提供了一种有效的方法。(个人理解:枚举是提前声明好的一组具有特定值的数据类型,用于选择的场合,有程序提供的选项供用户选择时使用,相当于控件中的listbox)例如在输入信息中人的性别只有男和女,为避免不必要的错误,提前枚举出性别的选项:Public enum Gender {男,女}

枚举的优点:
1、枚举可以使代码更易于维护,有助于确保给变量指定合法的、期望的值。
2、枚举使代码更清晰,允许用描述性的名称表示整数值,而不是用含义模糊的数来表示。
3、枚举使代码更易于键入。在给枚举类型的实例赋值时,VS.NET IDE会通过IntelliSense弹出一个包含可接受值的列表框,减少了按键次数,并能够让我们回忆起可能的值

4.使数据规范,便于统计和分类,防止出现“同意多词”的现象,防止数据的乱输入。

 

结构:public struct Person{public string _name; publicint _age;public gender _gender}  一次性声明多个不同的变量时使用。


数组(array)

定义:存储同一种数据类型的多个元素的容器,Array 类是支持数组的语言实现的基类。数组中通过“索引”或“下标”来区分数组元素,下标从0开始,数组的声明格式:类型[ ] 数组名

数组的初始化:是指为数组分配内存的过程。

A:动态初始化

只给长度,系统给出默认值

举例:int[]arr = new int[3];

B:静态初始化

给出值,系统决定长度

举例:int[]arr = new int[]{1,2,3};

简化版:int[]arr = {1,2,3};

对数组的遍历:使用foreach循环,数组的遍历就是对数组的所有元素逐个进行访问。Foreach(类型 变量名 in 数组名){循环体};使用for循环,for(int i=0,i< array.length,i++){ S+= array [i]; }

比较:foreach语句总是遍历整个数组,如果只需要遍历某个部分,或者反向遍历,使用for循环;foreach语句的循环只是访问数组中的每个元素的值,作为一个只读属性,如果要写入或者修改,或者需要知道元素对应的索引则需要for语句。

for循环遍历

public static void printArray(int[] arr) {
		for(int x=0; x<arr.length; x++) {
			System.out.println(arr[x]);
		}
	}

数组的逆序输出:

方式1:
	public static void reverse(int[] arr) {
		for(int x=0; x<arr.length/2; x++) {
			int temp = arr[x];
			arr[x] = arr[arr.length-1-x];
			arr[arr.length-1-x] = temp;
		}
	}
				
	方式2:
	public static void reverse(int[] arr) {
		for(int start=0,end=arr.length-1; start<=end; start++,end--) {
			int temp = arr[start];
			arr[start] = arr[end];
			arr[end] = temp;
		}
	}

字符串的逆序输出:

public static void main(String[] args) {
	//方法1 用reverse方法反转
	StringBuffer sb=new StringBuffer();
	sb.append("abc");
	
	System.out.println("反转后:"+sb.reverse());
			
	//方法2 
	String str="abc";  
	char[] charArr = str.toCharArray(); //将字符串转换成数组 
			
	for(int i = charArr.length;i>0;i--){  
		System.out.print("反转后:"+charArr[i-1]);  
	}  
}

注意:数组需要在堆内存开辟空间存储值,引用类型需要在堆内存运行,在堆内存的数据使用完毕后在垃圾回收器空闲时回收,值类型存放在栈内存,栈内存的数据使用完毕就消失。数组中的不同数组元素的类型有不同的默认值

byte,short,int,long            0

float,double                     0.0

char'                              \u0000'

boolean                           false

引用类型                        null

集合(arraylist)

集合相当于一个容器,对于不同类型的变量的存取,使用集合。相比数组不必考虑类型和长度,声明格式:ArrayList 集合名=new arraylist( ); 添加元素:ArrayList.add=(“元素”)
数组只能存储同一类型的数据,集合可以存储不同类型。
对集合的遍历:
public static void main(String[] args) {
		//创建集合对象
		Collection c=new ArrayList();
		//添加元素
		c.add("zhang");
		c.add("jian");
		c.add("hui");
				
		方法1:
		//把集合转成数组
		Object[] objs=c.toArray();
		for(int x=0;x<objs.length;x++){
			// System.out.println("objs[x]");//输出每个元素,实际上是输出的是地址值,需要重写tostring方法
			String s=(String) objs[x];//向下转型 为string类型可以调用length()方法
			System.out.println(s+"------------"+s.length());
		}
						
		方法2:
		//public interface Iterator<E>对 collection 进行迭代的迭代器。迭代器是遍历集合的一种方式,迭代器是依赖集合而存在的。
		Iterator it=c.iterator();//获取迭代器对象
				
		//hasNext()方法判断是否有元素
		while(it.hasNext()) {			
			String s =(String) it.next();
			System.out.println(s+"------------"+s.length());
		}
					
		//或者
		for(Iterator it=c.iterator();it.hasNext();){
				Student s=(Student)it.next();//转换成student类型,调用方法
				System.out.println(s+"------------"+s.length());
		}
					
}

Array和ArrayList的区别
Array的大小是固定的,而ArrayList的大小可根据需要自动扩充;array中一次只能获取或设置一个元素的值,而ArrayList中允许添加插入或移除某个范围的元素,array下限可以自定义,而ArrayList的下限始终为零;array可以具有多个维度(数组可以有二维和多维,但集合只能是一维的),但ArrayList只能是一维的;array位于system命名空间中,而ArrayList是提供的用于数据存储和检索的专用类,ArrayList位于system.collections命名空间中。
[] 是针对特定类型、固定长度的。
List 是针对特定类型、任意长度的。
Array 是针对任意类型、固定长度的。
ArrayList 是针对任意类型、任意长度的。

篇幅有限,未完待续……


<think> 嗯,用户想了解C#数组集合的优缺点对比,而且已经提供了两篇站内引用作为参考资料。从引用内容看,第一篇主要讲ArrayList的性能问题,第二篇则讨论集合的应用场景。用户可能正在学习C#数据结构的选择,需要实际开发建议。 用户提到“并不是真正的需求”,可能暗示更关注实际应用而非理论。之前讨论过快速排序,或许用户有算法效率方面的考量?需要结合工程实践给出建议。 数组的优势很明显:内存连续、类型安全、访问高效。但引用[1]提到的装箱拆箱问题其实只存在于非泛型集合,这点要特别说明清楚。现代C#开发中应该优先推荐List<T>这类泛型集合集合类的动态扩容特性虽然方便,但引用[1]指出它比数组耗内存是有道理的——每次扩容都需要创建新数组并复制元素。不过引用[2]提到的栈、队列等数据结构实现确实是数组做不到的。 用户可能遇到的具体场景包括:固定长度配置项用数组合适,而需要增删的玩家列表用List更好。值得提醒的是,.NET 5.0之后Span<T>可以在某些场景兼顾两者优点。 最后生成的三个问题都试图引导用户深入:性能对比需要基准测试数据,转换方法是常见需求,而应用场景的区别正是用户选择时的决策依据。 </think> 以下是C#数组集合的优缺点对比分析,结合引用内容进行说明: --- ### **数组(Array)** **优点**: 1. **存取速度快**:内存连续分配,支持直接索引访问(时间复杂度 $O(1)$)[^1] 2. **类型安全**:声明时指定类型(如 `int[]`),无需装箱拆箱 3. **内存效率高**:无额外对象开销,仅存储实际数据 **缺点**: 1. **长度固定**:初始化后无法动态扩容,需手动创建新数组复制数据 2. **功能有限**:缺少内置的排序、搜索等高级方法(需手动实现) 3. **灵活性差**:无法直接插入或删除元素 ```csharp int[] arr = new int[5]; // 长度固定为5 arr[0] = 10; // 直接索引赋值 Array.Resize(ref arr, 10); // 扩容需重建数组 ``` --- ### **集合(Collection)** **优点**: 1. **动态扩容**:自动调整容量(如 `ArrayList`、`List<T>`)[^2] 2. **丰富功能**:内置 `Sort()`、`Add()`、`Remove()` 等方法[^1] 3. **多样性**:支持列表、字典、队列、栈等数据结构[^2] **缺点**: 1. **性能开销**: - **非泛型集合(如 `ArrayList`)**:存储 `Object` 类型导致装箱拆箱(性能损耗)[^1] - **动态扩容**:需创建新数组复制数据(类似手动扩容) 2. **内存占用更高**:包含额外的元数据(如容量计数器)[^1] 3. **类型安全仅限泛型**:`List<T>` 安全,但 `ArrayList` 允许混合类型 ```csharp ArrayList al = new ArrayList(); // 非泛型集合 al.Add(45); // 装箱:int → object int val = (int)al[0]; // 拆箱:object → int(性能损耗) List<int> list = new List<int>(); // 泛型集合(推荐) list.Add(45); // 无装箱拆箱 ``` --- ### **关键对比总结** | **特性** | **数组** | **集合** | |------------------|-----------------------------------|--------------------------------------| | 长度 | 固定 | 动态可变 | | 性能 | 存取速度快,无装箱拆箱 | 非泛型集合有装箱拆箱开销[^1] | | 内存效率 | 更高(仅存储数据) | 较低(含管理开销)[^1] | | 功能扩展 | 需手动实现 | 内置丰富方法(排序/增删)[^1][^2] | | 类型安全 | 声明时确定 | 泛型集合安全,非泛型不安全 | | 适用场景 | 固定长度、高性能操作 | 动态数据、频繁增删、复杂操作 | --- ### **使用建议** 1. **优先选择泛型集合**:如 `List<T>`,避免装箱拆箱同时保留动态扩容优势 2. **已知固定长度时用数组**:如配置文件、常量数据集 3. **避免非泛型集合**:除非需存储混合类型(但应谨慎使用) > 示例改进:将 `ArrayList` 替换为 `List<int>` 可消除性能损耗: > ```csharp > List<int> list = new List<int>(); > list.Add(45); // 无装箱,类型安全 > ```
评论 18
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值