zoukankan      html  css  js  c++  java
  • C#集合基础与运用

    C#集合基础与运用

     转至:http://www.cnblogs.com/LiZhiW/p/3539839.html

    1.集合接口与集合类型

    (1)集合的命名空间

    大多数集合类都可以在 System.CollectionsSystem.Collections.Generic 名称空间中找到。

    泛型集合位于System.Collections.Generic 名称空间中;

    专用于特定类型的集合类位于System.Collections.Specialized名称空间中;

    线程安全的集合位于System.Collections.Concurrent名称空间中。

    (2)集合接口介绍

    1、IEnumerableIEnumerator 接口

    其实IEnumerable接口是非常的简单,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnumerator对象。

        public interface IEnumerable

        {

              IEnumerator GetEnumerator();

         }

    IEnumerator对象有什么呢?

    它是一个真正的集合访问器,没有它,就不能使用foreach语句遍历集合或数组,因为只有IEnumerator对象才能访问集合中的项。

    IEnumerator接口定义了:一个Current属性用来获取当前集合中的项;MoveNext方法将游标的内部位置向前移动;Reset方法将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。

    public interface IEnumerator
    {
        object Current { get; }
        bool MoveNext();
        void Reset();
    }

    一个collection要支持foreach进行遍历,就必须实现IEnumerable,并以某种方式返回迭代器对象:IEnumerator

    2、集合和列表实现的接口表

    接口

    说明

    IEnumerable<T>

    如果foreach语句用于集合,就需要此接口。

    ICollection<T>

    此集合定义了Count属性、CopyTo、Add、Remove、Clear方法

    IList<T>

    可以通过位置访问几何元素

    ISet<T>

    此集合不允许有重复的元素

    IDictionary<K,V>

    含有键值对的集合

    ILookup<K,V>

    含有键值对的集合,但可以通过一个键包含多个值

    IComparer<T>

    集合元素比较器,用于集合元素的排序

    IEqualityComparer<T>

    用于字典集合的比较器

    IProducerConsumerCollection<T>

    线程安全的集合

     

    2.集合的基本操作

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CollectionDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                #region 1、集合的基本操作
    
                //1)、创建集合
                //CreateCollection();
    
                //2)、添加元素至集合
                //AddCollection();
    
                //3)、插入元素至集合
                //InsertCollection();
    
                //4)、访问集合中的元素
                //VisitCollection();
    
                //5)、遍历集合
                //IteratesCollection();
    
                //6)、删除集合中的元素
                //DeleteCollection();
    
                //7)、查找元素
                //FindCollection();
    
                //8)、集合排序
                //SortCollection();
    
                //9)、集合数据类型转换
                //ConvertCollection();
    
                //11)、集合常见扩展方法Select
                //SelectCollection();
    
                //12)、集合常见扩展方法Where
                //WhereCollection();
    
                #endregion 集合的基本操作
    
                #region 2、常见集合的特性
    
                //队列(Queue)
                //QueueCollection();
    
                //栈(Stack)
                //StackCollection();
    
                //链表(LinkedList)
                //LinkedCollection();
    
                //有序列表(SortedList<K,V>)
                //SortedListCollection();
    
                //字典 Lookup
                //LookupCollection();
                #endregion 常见集合的特性
            
            }
    
            #region 1、集合的基本操作
    
            /// <summary>
            /// 1)、创建集合
            /// 使用默认的构造函数创建一个空集合,元素添加到集合之后,集合的容量就会扩大为4。
            /// 当集合的容量被使用完,且还在向集合中添加元素时,集合的容量就会扩大成原来的2倍!
            /// 可使用Capacity属性设置或访问集合的容量,使用Count属性访问集合的元素个数。
            /// 也可使用TrimExcess方法调整集合容量,节省内存!
            /// </summary>
            public static void CreateCollection()
            {
                List<int> list = new List<int>();
                //List<int> list = new List<int>(3); //指定初始容量
                //创建集合时可以为集合设置初始值 如下:
                //List<int> list1 = new List<int>() { 1,2,3,4,5,6,7,8,9,0};
                //List<string> list2 = new List<string>() { "aa", "bb", "cc" };
    
                for (int i = 0; i < 1025; i++)
                {
                    if (list.Count == list.Capacity)
                    {
                        Console.WriteLine("容量使用量:" + list.Count + "/" + list.Capacity);
                    }
                    list.Add(i);
                    Console.WriteLine("容量使用量:" + list.Count + "/" + list.Capacity);
                }
    
                Console.WriteLine("容量使用量:" + list.Count + "/" + list.Capacity);
                list.TrimExcess(); //整集合容量
                Console.WriteLine("容量使用量:" + list.Count + "/" + list.Capacity);
    
                Console.Read();
            }
    
            /// <summary>
            /// 2)、添加元素集合
            /// 为集合添加元素可使用Add方法,还可以使用AddRange方法一次添加多个元素,
            /// 因为AddRange方法的参数是IEnumerable<T>类型的对象,所以可以添加数组到集合里。
            /// </summary>
            public static void AddCollection()
            {
                List<string> list = new List<string>();
                
                list.AddRange(new string[] { "bb", "cc", "dd" }); //添加数组
                list.AddRange(list);
    
                list.Add("aa");
    
                foreach (string item in list)
                {
                    Console.WriteLine(item);
                }
                Console.Read();
            }
    
            /// <summary>
            /// 3)、插入元素至集合
            /// 插入元素可以使用Insert方法,同样使用InsertRange方法插入多个元素
            /// </summary>
            public static void InsertCollection()
            {
                List<string> list = new List<string>() { "aa", "bb","ff" };
                list.Insert(2, "cc"); //插入元素
                list.InsertRange(3, new string[] { "dd", "ee" }); //插入集合
    
                foreach (string item in list)
                {
                    Console.WriteLine(item);
                }
                Console.Read();
            }
    
            /// <summary>
            /// 4)、访问集合中的元素
            /// 使用索引器访问集合中某个位置的元素
            /// </summary>
            public static void VisitCollection()
            {
                List<string> list = new List<string>() { "aa", "bb", "cc", "ee" };
                Console.WriteLine(list[1]); //访问第1个位置上的元素,下标从0开始
                Console.Read();
            }
    
            /// <summary>
            /// 5)、遍历集合
            /// 集合的遍历,除了使用for、foreach外,还可以使用集合的Foreach方法,
            /// 该方法的参数是一个Action<T>委托类型,可以使用Lambda表达式
            /// </summary>
            public static void IteratesCollection()
            {
                List<string> list = new List<string>() { "aa", "bb", "cc" };
                list.ForEach(tmp => Console.WriteLine("元素:" + tmp));
                //也可以这样使用:list.ForEach(Console.WriteLine);
    
                Console.Read();
            }
    
    
            /// <summary>
            /// 6)、删除集合中的元素
            /// 使用RemoveAt删除指定位置的元素,使用Remove删除指定的元素,
            /// 使用RemoveRange删除指定位置范围的元素,使用Clear删除所有元素
            /// 使用RemoveAll选择删除的元素。注意:RemoveAll方法的参数是一个Predicate<T>委托类型
            /// </summary>
            public static void DeleteCollection()
            {
                List<string> list = new List<string>() { "12", "123", "1234", "12345" };
    
                //删除长度小于4的元素
                list.RemoveAll(x => { bool flag = x.Length < 4; return flag; });
                list.ForEach(Console.WriteLine);
    
                Console.Read();
            }
    
            /// <summary>
            /// 7)、查找元素
            /// 用于搜索的方法有:IndexOf、LastIndexOf、FindIndex、FindLastIndex、FindLast、Find、FindAll、Exists等方法。
            /// IndexOf、LastIndexOf、FindIndex、FindLastIndex 方法用于搜索元素的位置。
            /// FindLast、Find、FindAll 方法用于搜索满足条件的元素。
            /// Exists 用于判断集合是否存在某些元素。
            /// 参数可以使用Predicate<T>委托类型(Lambda表达式)的方法有:FindIndex、FindLastIndex、Find、FindLast、FindAll、Exists。
            /// </summary>
            public static void FindCollection()
            {
                List<string> list = new List<string>() { "12", "123", "1234", "12345" };
    
                list = list.FindAll(x => { bool flag = x.Length < 4; return flag; });
                list.ForEach(Console.WriteLine);
    
                Console.Read();
            }
    
            /// <summary>
            /// 8)、元素排序
            /// 可以使用Sort方法对元素排序,也可以调用Reverse方法逆转集合顺序,Sort方法使用快速排序算法
            /// Sort使用了几个重载的方法,可以传递的参数有泛型委托Comparison<T>和泛型接口IComparer<T>
            /// </summary>
            public static void SortCollection()
            {
                List<string> list = new List<string>() { "12", "123", "1234", "12345" };
    
                //按字符串长度排序
                list.Sort((x, y) => { return y.Length - x.Length; });
                list.ForEach(Console.WriteLine);
    
                Console.Read();
    
                #region Sort例子
                /*
                 // 把Student继承IComparer<Student>, IComparable<Student> 这两个接口,List<Student>就可以Sort了
                    public class Student : IComparer<Student>, IComparable<Student>        
                    {
                        public string name;
                        public int num;
    
                        //下面是一些方法及属性
                        public int Compare(Student s1, Student s2)
                        {
                            if (s1.num > s2.num)
                                return 1;
                            if (s1.num < s2.num)
                                return -1;
                            return 0;
                        }
    
                        public int CompareTo(Student s)
                        {
                            return Compare(this, s);
                        }
                    }
                    //测试
                    List<Student> l = new List<Student>();
                    Student s1 = new Student();
                    s1.num = 5;
                    Student s2 = new Student();
                    s2.num = 3;
                    Student s3 = new Student();
                    s3.num = 6;
    
                    l.Add(s1);
                    l.Add(s2);
                    l.Add(s3);
    
                    l.Sort();
                 */
                #endregion Sort例子
            
            }
    
            /// <summary>
            /// 9)、集合类型转换
            /// 使用ConvertAll<TOutput>方法可以把集合里的所有元素转换成另一种类型,ConvertAll<TOutput>使用了Converter委托,其定义如下:
            /// public sealeddelegate TOutput Converter<TInput, TOutput>(TInput from)
            /// TInput是委托方法的参数类型,TOutput是委托方法的返回值类型。例如:
            /// </summary>
            public static void ConvertCollection()
            {
                List<string> list = new List<string>() { "12", "123", "1234", "12345" };
    
                //把字符串集合转换成数字集合
                List<int> array = list.ConvertAll<int>(tmp => Int32.Parse(tmp));
                array.ForEach(Console.WriteLine);
                
                Console.Read();
            }
    
    
            //10)、只读集合
            //集合的AsReadOnly方法可以返回一个ReadOnlyCollection<T>类型的集合;
            //ReadOnlyCollection<T>是一个只读集合类型,除了不能使用修改集合的方法与属性,其它与集合一样。
    
            /// <summary>
            /// 11)、集合常用的扩展方法[Select]
            /// Select:将序列中的每个元素投影到新表中
            /// </summary>
            public static void SelectCollection()
            {
                List<int> list = new List<int>() { 1, 3, 5, 7, 9 };
                IEnumerable<string> array = list.Select<int, string>(x => (x * x).ToString());
    
                foreach (string s in array)
                {
                    Console.WriteLine(s);
                }
    
                Console.Read();
            }
    
    
            /// <summary>
            /// 12)、集合常用的扩展方法[Where]
            /// Where:基于谓词筛选值序列
            /// </summary>
            public static void WhereCollection()
            {
                List<string> list = new List<string> { "1", "12", "123", "1234" };
    
                //查询长度小于3的元素
                IEnumerable<string> query = list.Where(temp => temp.Length < 3);
    
                foreach (string s in query)
                {
                    Console.WriteLine(s);
                }
    
                Console.Read();
            }
    
            #endregion 集合的基本操作
    
            #region 2、常见集合的特性
    
            //(1)非泛型集合对应的泛型集合 
                // 非泛型集合类   对应的泛型集合类
                // ArrayList    List<T>
                // HashTable    DIctionary<T>
                // Queue        Queue<T>
                // Stack        Stack<T>
                // SortedList   SortedList
    
            /// <summary>
            /// 1、队列(Queue)
            /// 队列是其元素以先进先出的方式来处理的集合。该集合没有Add与Remove方法,其重要的方法:
            /// Enqueue():在队列的尾端添加元素
            /// Dequeue():在队列的头部读取并删除元素
            /// Peek()   :只读取队列头部的元素
            /// </summary>
            public static void QueueCollection()
            {
                Queue<string> queue = new Queue<string>();
    
                for (int i = 0; i < 5; i++)
                {
                    queue.Enqueue(i.ToString());//在尾部添加元素
                }
    
                PrintQueue(queue);//输出元素
    
                string s = queue.Dequeue(); //读取并删除头部元素
                Console.WriteLine("读取并删除头部元素:" + s);
    
                queue.Enqueue("5"); //在尾部添加元素
                s = queue.Peek(); //读取头部元素
                Console.WriteLine("读取头部元素:" + s);
    
                PrintQueue(queue);//输出元素
    
                Console.Read();
            }
    
            private static void PrintQueue(Queue<string> q)
            {
                IEnumerable<string> list = q.Where(t => true);
                foreach (string s in list)
                {
                    Console.WriteLine(s);
                }
            }
    
            /// <summary>
            /// 2、栈(Stack<T>)
            /// 栈是一个后进先出的容器,其重要的方法:
            /// Push() :在栈顶压入一个元素入栈
            /// Pop()  :从栈顶读取并删除一个元素
            /// Peek() :只从栈顶读取一个元素而不删除
            /// </summary>
            public static void StackCollection()
            {
                Stack<string> stack = new Stack<string>();
    
                for (int i = 0; i < 5; i++)
                {
                    stack.Push(i.ToString()); //入栈
                }
    
                PrintStack(stack); //输出
    
                string s = stack.Pop(); //读取并删除栈顶元素
                Console.WriteLine("读取并删除栈顶元素:" + s);
    
                s = stack.Peek();
                Console.WriteLine("只读取栈顶元素:" + s);
    
                PrintStack(stack);
    
                Console.Read();
            }
    
            private static void PrintStack(Stack<string> stack)
            {
                IEnumerable<string> list = stack.Where(t => true);
                foreach (var t in list)
                {
                    Console.WriteLine(t);
                }
            }
    
            /// <summary>
            /// 3、链表(LinkedList<T>/// LinkedList<T>是一个双向链表。
            /// 链表的优点是,如果将元素插入列表的中间位置,使用链表就会非常快,只需要修改下一个元素的Next引用与上一个元素的Previous引用。
            /// 链表不能在集合中只存储元素,必须要把元素存到LinkedListNode<T>类型的对象中,LinkedListNode<T>定义了属性:List、Next、Value、Previous。
            /// List属性返回与该节点相关的LinkedList<T>对象,Next、Previous用于遍历链表。
            /// 
            /// LinkedList<T>对象可以访问第一个和最后一个元素(Frist与Last)、
            /// 在指定位置插入元素(AddAfter()、AddBefore()、AddFirst()、AddLast()方法),
            /// 删除指定位置的元素(ReMove()、ReMoveFirst()、RemoveLast()方法),
            /// 从链表的开头(Find())或结尾(FindLast())开始搜索元素。
            /// </summary>
            public static void LinkedCollection()
            {
                LinkedList<int> link = new LinkedList<int>();
    
                LinkedListNode<int> node;
    
                for (int i = 0; i < 10; i++)
                {
                    node = new LinkedListNode<int>(i);
                    if (i % 2 == 0)
                    {
                        link.AddFirst(node); //从头部添加节点
                    }
                    else
                    {
                        link.AddLast(node);//从尾部添加节点
                    }
                }
    
                PrintLink(link); //输出元素
    
                Console.Read();
            }
    
            private static void PrintLink(LinkedList<int> link)
            {
                IEnumerable<int> list = link.Where(t => true);
                foreach (int t in list)
                {
                    Console.WriteLine(t);
                }
            }
    
            /// <summary>
            /// 4、有序列表(SortedList<K,V>)
            /// SortedList<K,V>是基于键对集合进行排序的集合类,它只允许每个键只有一个对应值,如果需要每个键对应多个值可以使用Lookup<K,V>/// 可以使用foreach遍历该集合,枚举器返回的是KeyValuePair<K,V>类型的元素。
            /// 除了使用Add方法添加元素,还可以使用索引器添加。
            /// </summary>
            public static void SortedListCollection()
            {
                SortedList<string, string> sort = new SortedList<string, string>();
    
                sort.Add("K1", "K1的值"); //Add方法添加元素
                sort["K2"] = "K2的值";    //索引器添加元素
    
                PrintSorted(sort);
    
                Console.WriteLine("是否存在[K3]:" + sort.ContainsKey("K3"));
    
                string value = null;
                Console.WriteLine("是否存在[K2]:" + sort.TryGetValue("K2",out value));
                Console.WriteLine("[K2的值]:" + value);
                Console.Read();
            }
    
            private static void PrintSorted(SortedList<string, string> sort)
            {
                IEnumerable<KeyValuePair<string, string>> list = sort.Where(tmp => true);
                foreach (KeyValuePair<string,string> item in list)
                {
                    Console.WriteLine(item.Key + " ----> " + item.Value);
                }
            }
    
    
            //5、字典
            /*
             * 字典中键的类型必须重写Object类的GetHashCode()方法。
             * 只要字典类需要确定元素的位置,他就会调用GetHashCode()方法。除了实现GetHashCode()方法外,键类型还必须实现IEquatable<T>.Equals()方法,或重写Object类的Equals()方法。
             * 因为不同的对象可能返回相同的散列码(GetHashCode方法返回值),但是如果A.Equals(B)返回true,则A和B的散列码就必须相同。
             * 这似乎有点奇怪,但这非常重要,因为字典的性能取决于GetHashCode()方法实现的代码。
            */
    
            //字典1): Dictionary<K,V>
            //      Dictionary<K,V>类支持每个键关联一个值,与SortedList<K,V>很类似,具体参考SortedList<K,V>。
    
    
            /// <summary>
            /// 字典2):Lookup<K,V>
            /// Lookup<K,V>类把键映射到一个值集上。
            /// 创建Lookup<K,V>类对象必须调用ToLookup()扩展方法,该方法返回一个Lookup<K,V>对象。
            /// ToLookup()方法需要一个Func<T,K>类型的委托参数,Func<T,K>类型定义了键的选择器。
            /// ToLookup()用于对一个集合进行操作,创建一个1:n 的映射。 它可以方便的将数据分类成组,并生成一个字典供查询使用。
            /// </summary>
            public static void LookupCollection()
            {
                List<string> list = new List<string>() { "1", "12", "123", "1234", "a", "ab", "abc" };
    
                var lookup = list.ToLookup(x => x.Length);
                foreach (var t in lookup)
                {
                    List<string> temp = t.ToList<string>(); //把一组数据转换成集合
                    temp.ForEach(x => Console.Write(x + "")); //输出集合
                    Console.WriteLine();
                }
    
                Console.Read();
            }
    
            /*
            * 字典3):SortedDictionary<K,V>
            * SortedDictionary<K,V>类是一个二叉搜索树,其中的元素根据键来排序,该键类型必须实现IComparable<T>接口。
            * SortedDictionary<K,V>与SortedList<K,V>的区别:
            * SortedList<K,V>类使用的内存比SortedDictionary<K,V>少。
            * SortedDictionary<K,V>类的元素的插入与删除比较快。
            * 在用于已排好序的集合,若不需要修改容量SortedList<K,V>会比较快。
            * 区别的根本原因:SortedList<K,V>实现的是一个基于数组的集合,SortedDictionary<K,V>实现的是一个基于字典的集合。
            */
    
            //6、集(ISet<T>接口)
            //不包含重复元素的集合称为集,.NET Framework包含两个集(HashSet<T>和SortedSet<T>),它们都实现ISet<T>接口。
            //HashSet<T>是不包含重复元素的无序列表,SortedSet<T>是不包含重复元素的有序列表。
    
    
            #endregion 常见集合的特性
    
        }
    }
    作者:郑某人 出处:http://jsonzheng.cnblogs.com 欢迎转载或分享,但请务必声明文章出处。如果文章对您有帮助,希望你能推荐或关注。
  • 相关阅读:
    对象关系一对多转换为一对一的方案——中介者模式总结
    接口转换的利器——适配器模式总结
    多线程场景设计利器:分离方法的调用和执行——命令模式总结
    对比总结三个工厂模式(简单工厂,工厂方法,抽象工厂)
    创建多个“产品”的方式——工厂方法模式总结
    Java反射+简单工厂模式总结
    最简单的设计模式——单例模式的演进和推荐写法(Java 版)
    对复合(协作)算法/策略的封装方法——装饰模式总结
    Java对象序列化全面总结
    创建产品族的方式——抽象工厂模式
  • 原文地址:https://www.cnblogs.com/jsonzheng/p/3540024.html
Copyright © 2011-2022 走看看