• 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就说这么多,如果有大神要补充的,请直接回复哈。共同进步!

  • 相关阅读:
    自定义组件要加@click方法
    绑定样式
    647. Palindromic Substrings
    215. Kth Largest Element in an Array
    448. Find All Numbers Disappeared in an Array
    287. Find the Duplicate Number
    283. Move Zeroes
    234. Palindrome Linked List
    202. Happy Number
    217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/chens2865/p/3852590.html
Copyright © 2020-2023  润新知