C# - Array与Collection


C# - Array与Collection

集合Collection

学习大纲

  • 数组、列表、哈希表、字典
  • 添加、删除、查询、更新

集合的特征

  • 确定性
  • 互异性
  • 无序性

C#中的集合类型

  • 所有集合都必须实现ICollection接口。
  • System.Collection(数组Array除外)

C#集合的特点

  • 可以储存无限个元素。
  • 任何一个集合都支持搜索、排序、复制、添加、删除等操作。

数组Array:固定长度的有序集合

数组Array

  • 固定长度。
  • 有明确的顺序。
  • 例如:一周7天:周一、周二、周三、周四、周五、周六、周日

实例

using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] daysOfWeek =
            {
                "Tuesday",
                "Monday",
                "Wendesday",
                "Thursday",
                "Friday",
                "Saturday",
                "Sunday"
            };

            foreach(var day in daysOfWeek)
            {
                Console.WriteLine(day);
            }

            // 零索引 0-indexed
            Console.WriteLine(daysOfWeek[0]);
            Console.WriteLine(daysOfWeek[1]);
            Console.WriteLine(daysOfWeek[6]);

            // 安全
            //Console.WriteLine(daysOfWeek[7]);

            // 固定长度
            string[] daysOfWeek2 = new string[7];
            daysOfWeek2[0] = "Monday";
            daysOfWeek2[1] = "Tuesday";
            daysOfWeek2[2] = "Wendesday";
            daysOfWeek2[3] = "Thursday";
            daysOfWeek2[4] = "Friday";
            daysOfWeek2[5] = "Saturday";
            daysOfWeek2[6] = "Sunday";

            Console.Read();
        }
    }
}

数组Array、列表List、数组列表ArrayList

实例

using System;
using System.Collections;
using System.Collections.Generic;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] daysOfWeek =
            {
                "Tuesday",
                "Monday",
                "Wendesday",
                "Thursday",
                "Friday",
                "Saturday",
                "Sunday"
            };

            foreach(var day in daysOfWeek)
            {
                Console.WriteLine(day);
            }

            // 零索引 0-indexed
            Console.WriteLine(daysOfWeek[0]);
            Console.WriteLine(daysOfWeek[1]);
            Console.WriteLine(daysOfWeek[6]);

            // 安全
            //Console.WriteLine(daysOfWeek[7]);

            // 固定长度
            string[] daysOfWeek2 = new string[7];
            daysOfWeek2[0] = "Monday";
            daysOfWeek2[1] = "Tuesday";
            daysOfWeek2[2] = "Wendesday";
            daysOfWeek2[3] = "Thursday";
            daysOfWeek2[4] = "Friday";
            daysOfWeek2[5] = "Saturday";
            daysOfWeek2[6] = "Sunday";

            //列表List
            List<string> daysOfWeek3 = new List<string>();
            //在List前加上“I”即可成为接口
            IList<string> daysOfWeek4 = new List<string>();
            daysOfWeek3.Add("Monday");
            daysOfWeek3.Add("Monday"); daysOfWeek3.Add("Monday"); daysOfWeek3.Add("Monday");
            daysOfWeek3.Add("Monday");

            //数组列表ArrayList
            var array = new ArrayList();
            array.Add(1);
            array.Add("123");
            array.Add(daysOfWeek);

            Console.Read();
        }
    }
}

List的创建、添加Add()、插入Insert

实例

using System;
using System.Collections;
using System.Collections.Generic;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] daysOfWeek =
            {
                "Tuesday",
                "Monday",
                "Wendesday",
                "Thursday",
                "Friday",
                "Saturday",
                "Sunday"
            };

            foreach(var day in daysOfWeek)
            {
                Console.WriteLine(day);
            }

            // 零索引 0-indexed
            Console.WriteLine(daysOfWeek[0]);
            Console.WriteLine(daysOfWeek[1]);
            Console.WriteLine(daysOfWeek[6]);

            // 安全
            //Console.WriteLine(daysOfWeek[7]);

            // 固定长度
            string[] daysOfWeek2 = new string[7];
            daysOfWeek2[0] = "Monday";
            daysOfWeek2[1] = "Tuesday";
            daysOfWeek2[2] = "Wendesday";
            daysOfWeek2[3] = "Thursday";
            daysOfWeek2[4] = "Friday";
            daysOfWeek2[5] = "Saturday";
            daysOfWeek2[6] = "Sunday";

            //列表List
            List<string> daysOfWeek3 = new List<string>();
            //在List前加上“I”即可成为接口
            IList<string> daysOfWeek0 = new List<string>();
            daysOfWeek3.Add("Monday");
            daysOfWeek3.Add("Monday"); daysOfWeek3.Add("Monday"); daysOfWeek3.Add("Monday");
            daysOfWeek3.Add("Monday");

            //ArrayList
            var array = new ArrayList();
            array.Add(1);
            array.Add("123");
            array.Add(daysOfWeek);

            //---------------------------------------------------------------------------------------
            //List的创建、添加Add()、插入Insert
            //List的创建
            var daysOfWeek4 = new List<string>(daysOfWeek3);
            var daysOfWeek5 = new List<string>(daysOfWeek);
            var daysOfWeek6 = new List<string>(7);
            Console.WriteLine($"{daysOfWeek6.Count} / {daysOfWeek6.Capacity}");
            daysOfWeek6.Add("Monday");
            daysOfWeek6.Add("Tuesday");
            daysOfWeek6.Add("Wendesday");
            daysOfWeek6.Add("Thursday");
            daysOfWeek6.Add("Friday");
            daysOfWeek6.Add("Saturday");
            daysOfWeek6.Add("Sunday");
            Console.WriteLine($"{daysOfWeek6.Count} / {daysOfWeek6.Capacity}");
            daysOfWeek6.Add("Sunday");
            Console.WriteLine($"{daysOfWeek6.Count} / {daysOfWeek6.Capacity}");

            List<string> daysOfWeek7 = new List<string>
            {
                "Tuesday",
                "Monday",
                "Wendesday",
                "Thursday",
                "Friday",
                "Saturday",
                "Sunday"
            };


            // Add AddRange
            //添加Add()
            daysOfWeek7.AddRange(daysOfWeek); //array
            daysOfWeek7.AddRange(daysOfWeek3); //List
            Console.WriteLine($"{daysOfWeek7.Count} / {daysOfWeek7.Capacity}");

            // Insert InsertRange
            //插入Insert
            daysOfWeek7.InsertRange(2, daysOfWeek);
            daysOfWeek7.Insert(2, "随便");
            Console.WriteLine(string.Join(", ", daysOfWeek7));

            daysOfWeek6.InsertRange(0, daysOfWeek7);
            daysOfWeek7.AddRange(daysOfWeek6);

            // 删除数据 RemoveAt RemoveRange
            daysOfWeek7.RemoveAt(0);
            daysOfWeek7.RemoveAt(2);
            daysOfWeek7.RemoveRange(2, 6);
            daysOfWeek7.Remove("Monday");
           
            //Lambda表达式(匿名方法、或箭头函数))
            daysOfWeek7.RemoveAll(i => i == "Monday");
            daysOfWeek7.RemoveAll(i => i.Contains("day"));
            Console.WriteLine(string.Join(", ", daysOfWeek7));
            
            //---------------------------------------------------------------------------------------

            Console.Read();
        }
    }
}

迭代器Enumerator与循环遍历ForEac

实例

Program.cs

using System;
using System.Collections;
using System.Collections.Generic;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] daysOfWeek =
            {
                "Tuesday",
                "Monday",
                "Wendesday",
                "Thursday",
                "Friday",
                "Saturday",
                "Sunday"
            };

            //-------续--上代码-----------

            /*            迭代器Enumerator与循环遍历ForEac*/
            // 12-6 读取数据
            var a = daysOfWeek6.Count;
            var b = daysOfWeek6.Capacity;

            // 索引器
            var c = daysOfWeek6[3];

            // 迭代器Enumerator
            List<string>.Enumerator enumerator = daysOfWeek6.GetEnumerator();

            //循环遍历ForEac
            foreach (var day in daysOfWeek6)
            {
                //day = "some day";
                Console.WriteLine(day);
                //daysOfWeek6.Add("one day");
            }

            List<Customer> customers = new List<Customer>();
            customers.Add(new Customer(1, "阿莱克斯", "广州"));
            customers.Add(new Customer(2, "莱克斯", "北京"));
            customers.Add(new Customer(3, "克斯", "上海"));
            customers.Add(new Customer(4, "斯", "深圳"));

            foreach (var customer in customers)
            {
                customer.Name = "123";
                Console.WriteLine(customer.Name);
            }

            Console.Read();
        }
    }
}

Customer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    public class Customer
    {
        public Customer(int id, string name, string address)
        {
            Id = id;
            Name = name;
            Address = address;
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }

    }
}

IEnumerable接口 vs IEnumerator

实例

Program.cs

using System;
using System.Collections;
using System.Collections.Generic;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {

/*            IEnumerable接口 vs IEnumerator*/
            var bank  = new Bank();
            foreach (var c in bank) {
                Console.WriteLine(c.Name);
            }


            Console.Read();
        }
    }
}

MyList.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    public class MyList<T> : IEnumerable<T>
    {
        private T[] _data;
        int currentIndex;

        public MyList(int length)
        {
            this._data = new T[length];
            currentIndex = 0;
        }

        public void Add(T obj)
        {
            _data[currentIndex] = obj;
            //currentIndex = currentIndex + 1;
            currentIndex++;
        }

        public IEnumerator<T> GetEnumerator()
        {
            return new MyEnumerator<T>(_data);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
}

MyEnumerator.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    public class MyEnumerator<T> : IEnumerator<T>
    {
        T[] _data;
        int _position = -1;

        public MyEnumerator(T[] data)
        {
            _data = data;
        }

        public T Current { get => _data[_position]; }

        object IEnumerator.Current { get => Current; }

        public void Dispose()
        {
          
        }

        public bool MoveNext()
        {
            _position = _position + 1;
            return _position < _data.Length;
        }

        public void Reset()
        {
            _position = -1;
        }
    }
}

Bank.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    public class Bank:IEnumerable<Customer>
    {
        public List<Customer> Customers { get; set; } = new List<Customer>();   
        public Bank() {
            Customers.Add(new Customer(1, "阿莱克斯", "广州"));
            Customers.Add(new Customer(2, "莱克斯", "北京"));
            Customers.Add(new Customer(3, "克斯", "上海"));
            Customers.Add(new Customer(4, "斯", "深圳"));
        }

        public IEnumerator<Customer> GetEnumerator()
        {
            return Customers.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
}

迭代与yield return

实例

using System;
using System.Collections;
using System.Collections.Generic;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
                        // yield retun
            var customers = GetCustomersYield(1000000);
            foreach (var c in customers)
            {
                if (c.Id < 3)
                {
                    Console.WriteLine($"客户id {c.Id}, 客户姓名: {c.Name}");
                }
                else
                {
                    break;
                }
            }

            //foreach (var i in CreateEnumerable())
            //{
            //    Console.WriteLine(i);
            //}

            Console.Read();
        }

        static IEnumerable<int> CreateEnumerable()
        {
            yield return 3;
            yield return 2;
            yield return 1;
        }

        static IEnumerable<Customer> GetCustomersYield(int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return new Customer(i, $"阿莱克斯{i}", "广州");
            }
        }

        static IEnumerable<Customer> GetCustomers(int count)
        {
            var customers = new List<Customer>();
            for(int i=0; i<count; i++)
            {
                customers.Add(new Customer(i, $"阿莱克斯{i}", "广州"));
            }
            return customers;
        }
    }
}

Benchmark性能基准测试

添加依赖项 —— benchmarkdotnet

实例

BenchmarkTester.cs

using BenchmarkDotNet.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    [MemoryDiagnoser]
    public class BenchmarkTester
    {
        // [  ] 特征
        [Benchmark]
        public void ProcessCustomer()
        {
            var customers = GetCustomers(1000000);
            foreach (var c in customers)
            {
                if (c.Id < 1000)
                {
                    Console.WriteLine($"客户id {c.Id}, 客户姓名: {c.Name}");
                }
                else
                {
                    break;
                }
            }
        }

        [Benchmark]
        public void ProcessCustomerYield()
        {
            var customers = GetCustomersYield(1000000);
            foreach (var c in customers)
            {
                if (c.Id < 1000)
                {
                    Console.WriteLine($"客户id {c.Id}, 客户姓名: {c.Name}");
                }
                else
                {
                    break;
                }
            }
        }

        static IEnumerable<Customer> GetCustomersYield(int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return new Customer(i, $"阿莱克斯{i}", "广州");
            }
        }

        static IEnumerable<Customer> GetCustomers(int count)
        {
            var customers = new List<Customer>();
            for (int i = 0; i < count; i++)
            {
                customers.Add(new Customer(i, $"阿莱克斯{i}", "广州"));
            }
            return customers;
        }
    }
}

Program.cs —— BenchmarkRunner方法

using BenchmarkDotNet.Running;
using System;
using System.Collections;
using System.Collections.Generic;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            //BenchmarkRunner方法
            var sumery = BenchmarkRunner.Run<BenchmarkTester>();

            Console.Read();
        }

        static IEnumerable<int> CreateEnumerable()
        {
            yield return 3;
            yield return 2;
            yield return 1;
        }

        static IEnumerable<Customer> GetCustomersYield(int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return new Customer(i, $"阿莱克斯{i}", "广州");
            }
        }

        static IEnumerable<Customer> GetCustomers(int count)
        {
            var customers = new List<Customer>();
            for(int i=0; i<count; i++)
            {
                customers.Add(new Customer(i, $"阿莱克斯{i}", "广州"));
            }
            return customers;
        }
    }
}

测试

编译为dll

  • dotnet build -c Release

执行该dll

  • dotnet (编译好的dll路径)
  • 极大提高了运行速度,实现了数据的懒加载,节省了内存空间。

数据搜索:字典

实例

using System;
using System.Collections;
using System.Collections.Generic;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            
            //var sumery = BenchmarkRunner.Run<BenchmarkTester>();
            
           //字典Dictionary
            var customers = GetCustomersDictionary(1000000);
            var customer = customers[999999];
            Console.WriteLine($"客户id {customer.Id}, 客户姓名: {customer.Name}");

            //hashtable 哈希表
            var customerHashtable = GetCustomersHashtable(1000000);
            var customer2 = (Customer)customerHashtable[999999];
            Console.WriteLine($"客户id {customer2.Id}, 客户姓名: {customer2.Name}");


            Console.Read();
        }

        static Hashtable GetCustomersHashtable(int count)
        {
            var customers = new Hashtable();
            for (int i = 0; i < count; i++)
            {
                customers.Add(i, new Customer(i, $"阿莱克斯{i}", "广州"));
            }
            return customers;
        }

        static Dictionary<int, Customer> GetCustomersDictionary(int count)
        {
            var customers = new Dictionary<int, Customer>();
            for (int i = 0; i < count; i++)
            {
                customers.Add(i, new Customer(i, $"阿莱克斯{i}", "广州"));
            }
            return customers;
        }

        static IEnumerable<int> CreateEnumerable()
        {
            yield return 3;
            yield return 2;
            yield return 1;
        }

        static IEnumerable<Customer> GetCustomersYield(int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return new Customer(i, $"阿莱克斯{i}", "广州");
            }
        }

        static IEnumerable<Customer> GetCustomers(int count)
        {
            var customers = new List<Customer>();
            for(int i=0; i<count; i++)
            {
                customers.Add(new Customer(i, $"阿莱克斯{i}", "广州"));
            }
            return customers;
        }
    }
}

测试

hashtable 哈希表

  • hashtable 哈希表不支持泛型,而字典dictionary支持泛型。

集合的交、并、差运算:HashSet

  • .NET 3.5在System.Collections.Generic命名空间中包含一个新的集合类:HashSet
  • 这个集合类包含不重复项的无序列表。这种集合称为“集(set)”。
  • 集是一个保留字,所以该类有另一个名称HashSet。这个名称很容易理解,因为这个集合基于散列值,插入元素的操作非常快,不需要像List类那样重排集合。
  • HashSet类提供的方法可以创建合集和交集。

实例

https://blog.csdn.net/baobingji/article/details/105564859

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - C# - Array与Collection


三二一的一的二