C# 集合(Collections),数组与集合的区别,集合与列表的区别

集合和数组集合的概念,以及区别:

数组是集合,但集合不一定是数组。

数组存储的类型不限制。集合存储的类型只能是引用类型。

数组(一般是相同数据类型,但object[]数组元素类型可以不同)的元素按一定顺序排列集合。

数组在添加,插入,删除等比方便,说明数组不是链表,但数组的读取(查询)速度比集合快。

集合是线性表,在插入,添加,删除数据时比较方面,性能比数组高。

C#中的集合(Collection)和数组(Array)是两种不同的数据结构,它们之间有以下主要区别:

  1.  定义方式不同:集合是使用集合类定义的,如List或HashSet。数组是使用类型和大小显式定义的。
  2. 大小不同:数组的大小在创建后无法更改,而集合的大小可以根据我们的需要动态增长。
  3. 内存布局不同:数组在内存中是连续的,而集合通常不是。
  4. 性能不同:访问数组元素通常比访问集合元素快,因为集合元素访问时可能需要进行装箱和拆箱操作。
  5. 索引访问:数组可以通过索引直接访问元素,而集合则需要使用迭代器或者在.NET 2.0及以上版本中使用foreach循环。
  6. 数据类型不同:数组可以存储基本数据类型(值类型),也可以存储引用类型,【而集合只能存储引用类型】,因为它们都继承自System.Object。

重要接口:

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable

数组实现了6个接口,前4个接口很重要

ICloneable接口控制克隆,复制对象

IList列表接口,控制对象操作(添加,删除等)

IEnumerable可枚举对象的接口,控制是对象的循环

ICollection集合接口,控制复制对象

public interface IList :ICollection,IEnumerable 说明列表也是集合的一种。

public class ArrayList:IList,ICollection,IEnumerable,ICloneable

Public class List<T>:IList<T>,ICollection<T>,IEnumerable<T>, IEnumerable,IList,ICollection,IReadOnlyList<T>,IReadOnlyCollection<T>

集合和列表(List<>类)的对比:

列表:表示可通过索引访问的对象的强类型列表。 提供用于对列表进行搜索、排序和操作的方法

List<T>类是类的泛型等效项 ArrayList 。 它 IList<T> 通过使用大小根据需要动态增加的数组来实现泛型接口。

  1. 定义和实现

    • 集合:在C#中,集合是一个泛指,可以是数组、列表、字典、栈、队列等。集合是.NET Framework中System.Collections命名空间下的一个接口或类。
    • 列表:列表是集合的一种具体实现,是泛型集合(List<T>),属于System.Collections.Generic命名空间。它提供了一种灵活的方式来存储和管理有序的数据项。
  2. 性能

    • 集合:性能取决于具体的集合类型。例如,ArrayList(非泛型集合)在添加和删除项时可能需要调整大小,这可能导致性能下降。
    • 列表:列表提供了快速的索引访问,因为它是基于数组实现的。添加和删除元素通常很快,尤其是当列表未满时。
  3. 类型安全

    • 集合:非泛型集合(如ArrayList)不是类型安全的,可以存储任何类型的对象。
    • 列表:列表是类型安全的,只能存储指定类型的元素。
  4. 灵活性

    • 集合:某些集合类型(如字典)提供了键值对的存储方式,这在某些场景下非常有用。
    • 列表:列表主要用于存储有序的元素集合,不支持键值对。
  5. 功能

    • 集合:不同的集合类型提供不同的功能。例如,队列(Queue)和栈(Stack)分别提供了先进先出(FIFO)和后进先出(LIFO)的数据结构。
    • 列表:列表提供了丰富的方法来添加、删除、查找和排序元素。
  6. 内存使用

    • 集合:某些集合类型可能会使用更多的内存来存储额外的信息,例如字典存储键和值的映射。
    • 列表:列表通常使用较少的内存,因为它只存储元素本身。
  7. 线程安全

    • 集合:大多数集合类型不是线程安全的,需要额外的同步机制来保证线程安全。
    • 列表:同样,List<T>也不是线程安全的。如果需要在多线程环境中使用,可以使用List<T>的线程安全版本,如ConcurrentBag<T>

ArrayList(非泛型集合类)

在C#中,ArrayList 是一个非泛型集合类,属于 System.Collections 命名空间。它提供了一种灵活的方式来存储和管理对象的有序集合。ArrayList 是一种动态数组,可以根据需要自动调整其大小。

public class ArrayList : IList, ICollection,IEnumerable, ICloneable

IList列表,ICollection集合

IEnumerable可枚举,可迭代,可循环   

ICloneable可克隆,可复制

ArrayList arrayList1 = new ArrayList();//没有指定容量(常用)
ArrayList arrayList2 = new ArrayList(3); //指定容量,提醒: 没有存储任何的项,长度还是0
ArrayList arrayList3 = new ArrayList(new int[] {1,2,3});//放一个实现ICollection接口的集合
  1. 动态数组ArrayList 可以自动调整其大小以适应添加的元素数量。这使得它在需要存储不确定数量的元素时非常方便。

  2. 类型不安全ArrayList 可以存储任何类型的对象,因为它的元素类型是 object。这意味着在使用元素时,可能需要进行类型转换,这可能会引入运行时错误。

  3. 添加和删除元素ArrayList 提供了 AddRemove 方法来添加和删除元素。当添加元素时,如果数组已满,ArrayList 会自动创建一个新的数组并将旧数组的元素复制到新数组中。注意:注意装箱,支持多种数据类型,取值时要拆箱。

    //添加
    arrayList1.Add(1);
    arrayList1.Add("ac");
    arrayList1.Add(true);
    //删除
    arrayList1.Remove("ac");//按值删除
    arrayList1.Remove(3);//按索引删除,有可能索引越界
  4. Rang范围,可以一次添加多个。

    arrayList1.AddRange(new object[] {"hello",false,213});
    arrayList1.AddRange(new List<int> {1,2,3 });
    arrayList1.AddRange(new Dictionary<string, string>()
    {
        {"key1","value1" },
        {"key2","value2" }
    });
  5. 索引访问:可以通过索引访问 ArrayList 中的元素,就像访问数组一样。索引从零开始。

    Console.WriteLine(arrayList1.IndexOf(1));  // 0
    Console.WriteLine(arrayList1.IndexOf("abc")); // 1
    Console.WriteLine(arrayList1.IndexOf(200));  // -1
    
    Console.WriteLine(arrayList1.LastIndexOf(1));  // 0
    Console.WriteLine(arrayList1.LastIndexOf("abc")); // 1
    Console.WriteLine(arrayList1.LastIndexOf(200));  // -1
  6. 容量和大小ArrayList 有一个 Capacity 属性,表示可以存储的最大元素数。还有一个 Count 属性,表示当前存储的元素数。

  7. 排序ArrayList 提供了 Sort 方法,可以对集合中的元素进行排序。

  8. 查找:可以使用 IndexOf 方法查找元素在 ArrayList 中的位置。

  9. 复制:可以使用 CopyTo 方法将 ArrayList 中的元素复制到一个数组中。

  10. 同步ArrayList 不是线程安全的。如果你需要在多线程环境中使用它,可以使用 ArrayList.Synchronized 方法创建一个线程安全的 ArrayList

  11. 清空

    arrayList1.Clear();

 实例:

using System;
using System.Collections;

class Program
{
    static void Main()
    {
        ArrayList list = new ArrayList();
        // 添加元素
        list.Add("Hello");
        list.Add(123);
        list.Add(DateTime.Now);
        // 访问元素
        Console.WriteLine(list[0]); // 输出 "Hello"
        Console.WriteLine(list[1]); // 输出 123
        Console.WriteLine(list[2]); // 输出当前日期和时间
        // 删除元素
        list.Remove(123);
        // 显示元素
        foreach (var item in list)
        {
            Console.WriteLine(item);
        }
        // 获取元素数量
        Console.WriteLine("Count: " + list.Count);
        // 获取最大容量
        Console.WriteLine("Capacity: " + list.Capacity);
    }
}

LIst列表

列表List对象,也是集合,并且是最流行集合

List列表中的数据类型是统一的

List<int>整体是一个类型,复合类型,List也是类型,int也是类型  <T>表示未知类型

也称泛型列表。和ArrayList集合最大区别:List列表中的项类型是统一的,而ArrayList集合中的项类型可以不同。

定义(格式):List<数据类型,类> 声明名字=new List<数据类型,类>(){值1,值2,值3};

List<int> list1 = new List<int>() { 1,1,1};
List<string> list2 = new List<string>() { "abc" };

Student one = new Student() { Id = 1, Name = "张三1" };
List<Student> student1 = new List<Student>() {
    one,
    new Student(){ Id=2,Name="张三1"},
    new Student(){ Id=3,Name="张三2"},
};

1.查询数据:

FindAll()正向查多项,Find()正向查一项,FindLast()倒查一项

List<Student> stus = student1.FindAll(stu => stu.Name == "张三1");

Student stu1 = student1.Find(stu => stu.Name == "张三1");

Student stu2 = student1.FindLast(stu => stu.Name == "张三1");

Console.WriteLine(stu1.Id);

Console.WriteLine(stu2.Id);

2.查索引  

IndexOf(), LastIndexOf(), FindIndex(), FindLastIndex()

int index1 = student1.IndexOf(one);//0

int index2 = student1.IndexOf(new Student() { Id = 1, Name = "张三1" });//-1

int index3 = student1.FindIndex(stu => stu.Id == 2);

Console.WriteLine(index1);  // 0

Console.WriteLine(index2);  // -1

Console.WriteLine(index3); // 1

3.添加

student1.Add(new Student() { Id = 3, Name = "李四" });

student1.AddRange(

 new Student[]

{

    new Student(){ Id = 4, Name = "李四1"},

    new Student(){ Id = 5, Name = "李四2"},

});

4.排序

student1.Sort(new ListCompare());
student1.ForEach(student =>
{
    Console.WriteLine(student);
});
//编号:3,名称:李四
//编号:4,名称:李四1
//编号:5,名称:李四2
//编号:1,名称:张三1
//编号:2,名称:张三1
//编号:3,名称:张三2

5.以下是 List<T> 的一些关键特性和用法:

  1. 类型安全List<T> 是泛型集合,只能存储类型为 T 的元素。这提供了编译时类型检查,避免了运行时的类型转换错误。

  2. 动态数组List<T> 可以根据需要自动调整其大小,就像 ArrayList 一样。但是,由于类型安全,List<T> 提供了更好的性能。

  3. 快速索引访问:由于 List<T> 是基于数组实现的,它提供了快速的索引访问能力。

  4. 添加和删除元素List<T> 提供了 AddAddRangeInsertRemoveRemoveAt 等方法来添加和删除元素。

  5. 查找元素:可以使用 IndexOfContainsFind 等方法来查找元素。

  6. 排序List<T> 提供了 Sort 方法,可以对集合中的元素进行排序。也可以使用 Sort 方法的重载版本,传入自定义的比较器。

  7. 反转List<T>Reverse 方法可以反转列表中元素的顺序。

  8. 复制:可以使用 CopyTo 方法将 List<T> 中的元素复制到数组中。

  9. 容量和计数List<T> 有一个 Capacity 属性,表示可以存储的最大元素数,以及一个 Count 属性,表示当前存储的元素数。

  10. 枚举器List<T> 可以被 foreach 循环直接遍历。

  11. 线程安全List<T> 不是线程安全的。如果需要在多线程环境中使用,可以使用 List<T> 的线程安全版本,如 ConcurrentBag<T> 或者使用锁来同步访问。

6.例子: 

internal class Program
{
    static void Main()
    {
        List<int> numbers = new List<int>();
        // 添加元素
        numbers.Add(10);
        numbers.Add(20);
        numbers.Add(30);
        // 访问元素
        Console.WriteLine(numbers[1]); // 输出 20
        // 删除元素
        numbers.Remove(20);
        // 显示元素
        foreach (var number in numbers)
        {
            Console.WriteLine(number);
        }
        // 获取元素数量
        Console.WriteLine("Count: " + numbers.Count);
        // 获取最大容量
        Console.WriteLine("Capacity: " + numbers.Capacity);
        // 排序
        numbers.Sort();
        // 反转
        numbers.Reverse();
    }
}

  • 31
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值