• .NET常用集合类


    一、先来集合与数组的区别

    1.数组是固定大小的,不能伸缩。虽然System.Array.Resize这个泛型方法可以重置数组大小,但是该方法是重新创建新设置大小的数组,用的是旧数组的元素初始化。随后以前的数组就废弃!而集合却是可变长的。

    2.数组要声明元素的类型,集合类的元素类型却是object。

    3.数组可读可写不能声明只读数组。集合类可以提供ReadOnly方法以只读方式使用集合。

    4.数组要有整数下标才能访问特定的元素,然而很多时候这样的下标并不是很有用。集合也是数据列表却不使用下标访问。很多时候集合有定制的下标类型,对于队列和栈根本就不支持下标访问!

    二、C#中的集合类

    集合,表示可以通过遍历每个元素来访问的一组对象(特别是可使用foreach循环访问)
    一个集合包括多个元素,即有一个集合类对象和N个元素对象

    ---------------------------

    因为任何集合类都实现了IEnumerable接口,所以任何集合类对象都有一个GetEnumerator()方法,该方法可以返回一个实现了IEnumerator接口的对象,这个返回的IEnumerator对象既不是集合类对象,也不是集合的元素类对象,它是一个独立的类对象。通过这个对象,可以遍历访问集合类对象中的每一个元素对象

    如果集合类是用户自定义的集合类,则用户必须实现它的GetEnumerator()方法,否则不能使用循环。当然,与这个自定义集合类对应的IEnumerator类(实现了该接口的类),也要自定义一个才行

    比如,ArrayList集合类对应的IEnumerator是 ArrayListEnumeratorSimple
                Array集合类对应的IEnumerator是 SZArrayEnumerator
          (这两个类在.net work类库文档(msdn)中都没有介绍)

    ------------------------

    1.System.Colloctions中表示集合的行为的接口有:
    1)ICollection
    定义所有集合的大小、枚举数和同步方法。派生于IEnumerable
    它定义了集合类最基本的行为,所有的集合类都实现了这个接口(基接口)
    但是它的行为太过基本:主要就是一个Count属性,单独实现它没有太大意义

    2)IEnumerable
    公开枚举数,该枚举数支持在集合上进行简单迭代
    它只有一个方法 GetEnumerator(),该方法可以返回一个IEnumerator接口,通过它可以遍历集合
    基本上所有的集合类都实现了这个接口

    3)IList
    IList实现是可排序且可按照索引访问其成员的值的集合,它本身实现了ICollection和IEnumerable接口
    是所有列表的抽象基类。IList 实现有三种类别:只读、固定大小、可变大小。

    4)IDictionary
    IDictionary实现是键/值对的集合,它本身实现了ICollection和IEnumerable接口
    是键/值对的集合的基接口。IDictionary 实现有三种类别:只读、固定大小、可变大小。
    IDictionary可称为字典、映射或散列表,它根据键(任意类型)来访问值

    ------------------------------

    2.System.Collections中可以直接使用的集合类有:
    1)ArrayList
    实现了接口:IList、ICollection、IEnumerable
    只要集合未被修改,ArrayList 就可安全地同时支持多个读取器
    随着向 ArrayList 中添加元素,容量通过重新分配按需自动增加(2倍增加)
    如果需要建立一个对象数组,但不能预先知道数组的大小,就可以使用ArrayList
    ArrayList把所有元素都当作object对象引用,因而在访问ArrayList的元素时要进行类型转换
    优点:动态改变大小、灵活方便的插入和删除元素、可排序
    缺点:插入时性能不如数组、不是强类型的

    2)BitArray
    实现了接口:ICollection、IEnumerable
    管理位值的压缩数组。

    3)Hashtable
    实现了接口:IDictionary、ICollection、IEnumerable
    可以向Hashtable中自由添加和删除元素,有些像ArrayList,但没有那么大的性能开销

    4)SortedList
    实现了接口:IDictionary、ICollection、IEnumerable
    SortedLIst兼顾了ArrayList和Hashtable的优点,可按键值来排序

    5)Queue
    实现了接口:ICollection、IEnumerable
    Queque是队列,先进先出的访问各个元素
    可以调用Queque对象的GetEnumerator()方法,得到IEnumerator对象,来遍历队列中的各个元素

    6)Stack
    实现了接口:ICollection、IEnumerable
    Stack是堆栈,后进先出的访问各个元素
    可以调用Stack对象的GetEnumerator()方法,得到IEnumerator对象,来遍历堆栈中的各个元素

    ----------------

    3.上面提到的几种集合类,他们都是通用的集合类,他们所接受的元素大都是Object类型,当对象放入
    了集合之后,都失去了原有的类型信息-即这些通用集合类都不是强类型的
    解决办法是使用强类型的集合类
    System.Collections命名空间下的CollectionBase,DictionaryBase,ReadOnlyCollectionBase 类
    System.Collections.Specialized命名空间下的一些类可以满足要求,可以直接使用也可以继承


    三.类型安全的泛型

    泛型是为保证类型安全的出现的,她允许你在编译时实现类型安全。泛型包括泛型类和泛型方法。泛型一般是在集合中使用
       public class MyGeneric<T> //泛型类的定义:类名后跟<T>,T可以换成其他字母
        {
            private T name; // 泛型的使用
            public T Name
            {
                get { return this.name; }
                set { this.name = value; }
            }

            public List<S> Copy<S>(List<S> t1, List<S> t2) // 泛型方法的例子
            {
                foreach (S t in t1)
                {
                    t2.Add(t);
                }
                return t2;
            }
        }
       非泛型集合不安全的例子,该错误只能在运行时发现,编译允许通过。
    static void Main(string[] args)
      {
       ArrayList list = new ArrayList();
       list.Add(3);
       list.Add(4);
         list.Add(5.0);
       int total = 0;
       foreach(int val in list)
       {
        total = total + val;
       }
       Console.WriteLine("Total is {0}", total);
      }
     问题出在:list.Add(5.0);当执Add操作时,系统执行装箱操作,而在foreach(int val in list)的循环中,系统又对每个list中的成员执行拆箱操作,将3和4拆箱成int没有问题,但是,5.0是double类型,拆箱成int就抛出异常了。

  • 相关阅读:
    Longest Substring Without Repeating Characters
    Longest Valid Parentheses
    LInux下编译发生的libc相关错误
    【转载】字符编码笔记:ASCII,Unicode和UTF-8
    Python深入:super函数
    Python基础:常用函数
    25最小操作数问题
    24字符串最短编辑距离
    23最大乘积子串
    22倒排索引简介
  • 原文地址:https://www.cnblogs.com/im/p/1439199.html
Copyright © 2020-2023  润新知