zoukankan      html  css  js  c++  java
  • C#集合之ArrayList

    C#中之所以有集合这个东东,是因为数组的长度是固定的,而实际需求是,不确定未来这个“数组”的个数,故出现集合这个概念,因为集合的容量会随元素的增加曾倍数增长。C#中有2类常用集合:ArrayList,泛型版本是List<T>(类似数组集合)和Hashtable,泛型版本是Dictionary<K,V>(键值对集合),现在讨论下ArrayList集合

    刚才说集合的容量会随元素的增加曾倍数增长,请看代码:

    1             ArrayList aList = new ArrayList();
    2             aList.Add(9);
    3             aList.Add(new Person() { ID = 1, Name = "yzk", Age = 18 });
    4             aList.Add("80");
    5             aList.AddRange(new int[] { 4, 5, 6, 7, 8 });
    6             aList.AddRange(new string[] { "张三", "李四", "王五" });
    7             Console.WriteLine("容量:" + aList.Capacity);
    8             Console.WriteLine("含元素个数:" + aList.Count);
    9             Console.ReadKey();

    运行结果如下:

    需要注意的是,集合中的Add方法只能添加一个元素,哪怕里面是数组也只认为是一个元素,而AddRange则认为添加“一些”元素,里面每个元素都是集合中的单个元素。

    当容量为8,元素<=8时不增长,>8后,增加至16.

    调用ArrayList的Remove()和RemoveAt(),可以删除集合中的元素。

     1 ArrayList aList = new ArrayList();
     2             aList.Add(9);
     3             aList.Add(new Person() { ID = 1, Name = "yzk", Age = 18 });
     4             aList.Add("80");
     5             aList.AddRange(new int[] { 4, 5, 6, 7, 8 });
     6             aList.AddRange(new string[] { "张三", "李四", "王五" });
     7             aList.Add(new string(new char[]{'a','b','c'}));
     8             aList.Remove("80");
     9             aList.Remove("abc");
    10             Console.WriteLine("容量:" + aList.Capacity);
    11             Console.WriteLine("含元素个数:" + aList.Count);

    运行结果如下:

    Count为集合中实际包含元素的个数,而Capacity代表容量。

    这里有一个疑问,Remove()是根据对象来删除元素,但是可以看到new string(new char[]{'a','b','c'})"abc"不是一个东西,前者是new出来的,那么在堆内存中肯定创建了对象,而后者是字符串常量。为何Remove()还能删掉呢?编译得知,Remove删除的时候,是调用对象的Equal()方法在判断2个对象是否相同,即只要值相同就认为是一个对象。

    需要注意的是,如果要清空集合中的元素,不能在foreach中遍历删除,因为foreach在遍历时要求对象个数不能变。也不能调用for循环删除,请看下面的代码:

     1 ArrayList aList = new ArrayList();
     2             aList.Add(9);
     3             aList.Add(new Person() { ID = 1, Name = "yzk", Age = 18 });
     4             aList.Add("80");
     5             aList.AddRange(new int[] { 4, 5, 6, 7, 8 });
     6             aList.AddRange(new string[] { "张三", "李四", "王五" });
     7             aList.Add(new string(new char[]{'a','b','c'}));
     8             for (int i = 0; i < aList.Count; i++)
     9             {
    10                 aList.Remove(aList[i]);
    11             }
    12             Console.WriteLine("容量:" + aList.Capacity);
    13             Console.WriteLine("含元素个数:" + aList.Count);

    我们的设想是,集合中的元素清空了,即Count为0,但实际结果如下:

    为什么会出现这种情况呢?调试可以看到,在这样删除元素的时候,集合的Count总在变,当删除第0个时,集合中的Count-1,原来的第1个元素变成第0个,而再删除第1个元素时,实际删除的是原来元素+1个元素,就造成了漏删除的问题,所以要清空ArrayList集合中的元素,只能调用其Clear()方法。

    下面说一下,ArrayList集合排序的问题:

    调用ArrayList集合的Sort()方法可实现排序:

    1 ArrayList alist = new ArrayList();
    2             alist.AddRange(new int[] { 3, 8, 4, 22, 59, 20, 55, 74, 33 });
    3             alist.Sort();       //如果集合中的对象都是数值,默认是可以根据升序排序的
    4             foreach (var item in alist)
    5             {
    6                 Console.WriteLine(item);
    7             }

    但是更多的时候是, ArrayList中是几个对象,那如何实现排序呢?有2种方法,下面分别写出:

    1.让对象实现IComparable接口:

     1 class Person : IComparable
     2     {
     3         public int Id { get; set; }
     4         public string Name { get; set; }
     5         public int Age { get; set; }
     6 
     7         //定义排序规则(依据年龄来排序)
     8         public int CompareTo(object obj)
     9         {
    10             Person p = obj as Person;
    11             return this.Age-p.Age;
    12         }
    13     }

    这样,一个排序规则就定义好了,是按照年龄升序排列(如果要实现倒序,将CompareTo中换成p.Age-this.Age即可)

    ArrayList aList = new ArrayList();
                Person p1 = new Person() { Id = 1, Name = "yzk", Age = 18 };
                Person p2 = new Person() { Id = 2, Name = "jk", Age = 22 };
                Person p3 = new Person() { Id = 3, Name = "sk", Age = 20 };
                aList.AddRange(new Person[] { p1, p2, p3 });
                aList.Sort();
                foreach (var item in aList)
                {
                    Person p = item as Person;
                    Console.WriteLine(p.Name + "  " + p.Age);
                }

    2.在Person类外面定义排序方法的类,实现IComparer接口,代码如下:

    class SortByName : IComparer
        {
            public int Compare(object x, object y)
            {
                Person px = x as Person;
                Person py = y as Person;
                return px.Name.Length - py.Name.Length;
            }
        }
    
        class SortByAge : IComparer
        {
            public int Compare(object x, object y)
            {
                Person px = x as Person;
                Person py = y as Person;
                return px.Age - py.Age;
            }
        }

    这里我定义了2个排序规则,都实现IComparer接口.使用排序的代码如下:

     1 ArrayList aList = new ArrayList();
     2             Person p1 = new Person() { Id = 1, Name = "yzk", Age = 18 };
     3             Person p2 = new Person() { Id = 2, Name = "jk", Age = 22 };
     4             Person p3 = new Person() { Id = 3, Name = "sk", Age = 20 };
     5             aList.AddRange(new Person[] { p1, p2, p3 });
     6             aList.Sort(new SortByName());
     7             foreach (var item in aList)
     8             {
     9                 Person p = item as Person;
    10                 Console.WriteLine(p.Name + "  " + p.Age);
    11             }

    这样,如果需求变化了,我只需在声明一个类,实现IComparer接口即可。然后调用集合的Sort方法时,将类new出来的对象放进去就好了。

    好了,关于ArrayList就说这么多,如果有大神要补充的,请直接回复哈。共同进步!

  • 相关阅读:
    IDEA 2021.1 推出语音、视频功能,边写代码边聊天
    HTML5实现首页动态视频背景
    前端项目自动化构建工具——Webpack入门教程
    JavaScript多线程及事件循环机制
    SVN迁移至Git,保留commit提交记录
    Windows平台下搭建自己的Git服务器
    SVN服务器搭建、备份及多服务器同步方案(Windows)
    全图文分析:如何利用Google的protobuf,来思考、设计、实现自己的RPC框架
    注册表修改右键菜单的说明
    powershell换行输出,换行输入命令,多行命令的执行
  • 原文地址:https://www.cnblogs.com/chens2865/p/3852590.html
Copyright © 2011-2022 走看看