C#集合之ArrayList
C#中之所以有集合这个东东,是因为数组的长度是固定的,而实际需求是,不确定未来这个“数组”的个数,故出现集合这个概念,因为集合的容量会随元素的增加曾倍数增长。C#中有2类常用集合:ArrayList,泛型版本是List<T>(类似数组集合)和Hashtable,泛型版本是Dictionary<K,V>(键值对集合),现在讨论下ArrayList集合。
刚才说集合的容量会随元素的增加曾倍数增长,请看代码:
ArrayList aList = new ArrayList();
aList.Add();
aList.Add(new Person() { ID = , Name = "yzk", Age = });
aList.Add("");
aList.AddRange(new int[] { , , , , });
aList.AddRange(new string[] { "张三", "李四", "王五" });
Console.WriteLine("容量:" + aList.Capacity);
Console.WriteLine("含元素个数:" + aList.Count);
Console.ReadKey();
运行结果如下:
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIMAAAAxCAIAAAB2/Y1PAAACXUlEQVR4nO2YQZKEIAxFvf+pOMVcpjez6JouhiSfH4iatvJWigghj9i2x6vIwdGf/BT3MZo4BK012VjEMzVxcDKaTWzAj0WaADkFKbYyXiZYVBPMjdJE1cQWg4k+cTKJnxZwiWz3oo7zKNnW74SlhC+FwOJQb3+OgzeqCZl6XCvnYYl8moZj9u7ECzijFIbBccvXA0yoDwRrHPJptoZlIlD2/VhPJ2t51iVXTXjTh2viITLku1P7+2EAmVVTMz3uG8vECPPu1INrhawJL2VCgVnztA+fO+A1Vvb93FITz0lfIMDE8tOmsrzCfk0AZ097gJwK/mf35uw8escn+6ubxjXRpYSY8BbEZgHhDq17p7IOMjI10cR3p3BcgzPx9H3a/9ctb2zXEfXdyctaQbjimdbiStznMf3udMGeIodVMytbLLtrC7F6xqeC+e40HMtTkoX+05Wr7U17Oi2YkGHg9i2s707DxHyI4C4Vphu2Yp0OByA26R5sCLU9APx0wvtU4jUx3fjenWEFAOrj0EyA2UH7Fsxb7Gf66Wi8iQXNy5EMja6J0pkgJ/bWxKena2GgMxb8lSbUJeEImij56exywOX9bnVgxreWlsWE2n/ZxJAdDI4Zd+DDkPGo7VZ/HKSbKBPqMpgbXT2ZDn2a1JH5YpWbw7tpHISYYBrBqZU4Cz6V6o3x2zmE/d8JvNnVG4fUq5cATNHgkTPK2KyJhSVNR2ASDS6p4y/McjX8/4niXMpEFspEFspEFspEFspEFspEFspEFspEFspEFspEFspEFgYT5PfXIp4ykYUykYRfdN6ahkDbz8MAAAAASUVORK5CYII=" alt="" />
需要注意的是,集合中的Add方法只能添加一个元素,哪怕里面是数组也只认为是一个元素,而AddRange则认为添加“一些”元素,里面每个元素都是集合中的单个元素。
当容量为8,元素<=8时不增长,>8后,增加至16.
调用ArrayList的Remove()和RemoveAt(),可以删除集合中的元素。
ArrayList aList = new ArrayList();
aList.Add();
aList.Add(new Person() { ID = , Name = "yzk", Age = });
aList.Add("");
aList.AddRange(new int[] { , , , , });
aList.AddRange(new string[] { "张三", "李四", "王五" });
aList.Add(new string(new char[]{'a','b','c'}));
aList.Remove("");
aList.Remove("abc");
Console.WriteLine("容量:" + aList.Capacity);
Console.WriteLine("含元素个数:" + aList.Count);
运行结果如下:
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAAxCAIAAABh3x2GAAACZElEQVR4nO2YUXaEIAxF3f+qWEU3059+9HQOQ5LHC0TN2NwvRcSQSxyH47vIynF3AIVJuclLuclLucnLm5uvIhOjm0PQWpONxRVM3RycnmYTG/A/QroBWQZJtxyUm3VUN8yN0k3VTTCDmz6VMq2vFnCJbPeijvNw/dbvjSWJL5fAAlJvf7KVX1Q3Ugaup/Ow1D5fzDH7TuOVnFEuw+C45YEAN+prxBqHfAeuYbkJ1J8R651mTdi65Kobb0Jx3TxWj/xOa38/MCDXarKmx31juZnDfKf14Hoi68ZLudly4+rDZxOYjtWfkVvq5skJDQS4WX5HVd5j2K8bYPH5r51Twf89fzk7s97xyf7qMnI96GZC3HiLZrPIcIfWfb9ZB5/B1E0T+2nhuAZn4un7tPdPO29sdxK1n+ZlrWhc8UzrdSXuK5nup12w7shh1VzLFsv32kTuFMzspw3H8pRkob8aw7S9ae80a0YANQyQjWCs/bQhINkCkmLdpcJ0w56s0+EAxCZXA1gi/bCXulEjtgKVeN1Mi8O7VqwAhqtTN9bT+wfd6UYGOh2Nd7MgfjmSodH1IOBG7RAJ6YaMwFs3r56uGYLOWHmUm6F6+Mh9BO6nyWlMn65OnrmL78CMb00NuLE6RLK/n2ZdAqdAPDNb3IEPQ8ajtoOWz3CjToy50dWT6TCsa3kjk02wXFzLaIsQN0wjOLVSacEnV73x3IQGsv97gwvCWnr9gXoJwBQWHvkz9GzWzcIkpyMwqQeX1PEXnnI//P+b4mrKTV7KTV7KTV7KTV7KTV7KTV7KTV7KTV7KTV7KTVp+AEQGyd6QEUIoAAAAAElFTkSuQmCC" alt="" />
Count为集合中实际包含元素的个数,而Capacity代表容量。
这里有一个疑问,Remove()是根据对象来删除元素,但是可以看到new string(new char[]{'a','b','c'})和"abc"不是一个东西,前者是new出来的,那么在堆内存中肯定创建了对象,而后者是字符串常量。为何Remove()还能删掉呢?编译得知,Remove删除的时候,是调用对象的Equal()方法在判断2个对象是否相同,即只要值相同就认为是一个对象。
需要注意的是,如果要清空集合中的元素,不能在foreach中遍历删除,因为foreach在遍历时要求对象个数不能变。也不能调用for循环删除,请看下面的代码:
ArrayList aList = new ArrayList();
aList.Add();
aList.Add(new Person() { ID = , Name = "yzk", Age = });
aList.Add("");
aList.AddRange(new int[] { , , , , });
aList.AddRange(new string[] { "张三", "李四", "王五" });
aList.Add(new string(new char[]{'a','b','c'}));
for (int i = ; i < aList.Count; i++)
{
aList.Remove(aList[i]);
}
Console.WriteLine("容量:" + aList.Capacity);
Console.WriteLine("含元素个数:" + aList.Count);
我们的设想是,集合中的元素清空了,即Count为0,但实际结果如下:
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAAAvCAIAAAC0Wtk+AAACMUlEQVRoge2YUZaDMAhFs/9VZRWzGX/mw9ajIbw8CDqZlvulESNeiNaWLQml/HUCn0YKDaZs2/aTxPESWgS1VjmYjNGEFs5p1YnN899wCAVqgClNXAplFUih2aEXdqHn+5cujhFwiBy30p1n6Zo1z1DNLN+Yga3aPX1dlTtnodIg7tz70Oqxus2ivOV5j3c0ZjM5HlkOKbS7yrTTyUeED01oYM3iaZa8lqV2yNShVgu4Qxd1erzl6/uhCQR173C4fR78FqHHLuhQbZzvUCvfKNQUwysA5YmtWTxPdui6FgKRQt1L+PNlMbg7FKhffVXeyuTfdzNY5yfju7U3XWiKGaHW9pxsZxxQT29/beMJ8D/2t6ZimpzJ5xxTrz8MrLn5mfyWt+JrT1M+w5XhyZtH+5Z/oMLktF1BckQrkuNGptSDb/lmW+6SOOKHCrrjtbfkrUL9Kneab3mZH3Mxa9JkGJar7TYbIDdZwlmbRVnyuGskji4Au0W5MRCmJQC6tTwmtMEqCMc7quXOpBkkT3ckdgELJSe1dugRaUoaBOM6WYX60nsx/y1fR+sX5206iw9g5u+qjxc6zBUfArugWkz2OIBPQ+bTjMhtA/N/3+GRwNYeCj27kCeSdvgC95kRygzihsUXZS4nY7QaOwVZcT9Dcet1T2wMdg8BmBbGMz/h1NehjsyGM8wseVlyrStvdzr8HZrYSKHBpNBgUmgwKTSYFBpMCg0mhQaTQoNJocGk0Fh+AVZ2tge2Ed3AAAAAAElFTkSuQmCC" alt="" />
为什么会出现这种情况呢?调试可以看到,在这样删除元素的时候,集合的Count总在变,当删除第0个时,集合中的Count-1,原来的第1个元素变成第0个,而再删除第1个元素时,实际删除的是原来元素+1个元素,就造成了漏删除的问题,所以要清空ArrayList集合中的元素,只能调用其Clear()方法。
下面说一下,ArrayList集合排序的问题:
调用ArrayList集合的Sort()方法可实现排序:
ArrayList alist = new ArrayList();
alist.AddRange(new int[] { , , , , , , , , });
alist.Sort(); //如果集合中的对象都是数值,默认是可以根据升序排序的
foreach (var item in alist)
{
Console.WriteLine(item);
}
但是更多的时候是, ArrayList中是几个对象,那如何实现排序呢?有2种方法,下面分别写出:
1.让对象实现IComparable接口:
class Person : IComparable
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; } //定义排序规则(依据年龄来排序)
public int CompareTo(object obj)
{
Person p = obj as Person;
return this.Age-p.Age;
}
}
这样,一个排序规则就定义好了,是按照年龄升序排列(如果要实现倒序,将CompareTo中换成p.Age-this.Age即可)
ArrayList aList = new ArrayList();
Person p1 = new Person() { Id = , Name = "yzk", Age = };
Person p2 = new Person() { Id = , Name = "jk", Age = };
Person p3 = new Person() { Id = , Name = "sk", Age = };
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接口.使用排序的代码如下:
ArrayList aList = new ArrayList();
Person p1 = new Person() { Id = , Name = "yzk", Age = };
Person p2 = new Person() { Id = , Name = "jk", Age = };
Person p3 = new Person() { Id = , Name = "sk", Age = };
aList.AddRange(new Person[] { p1, p2, p3 });
aList.Sort(new SortByName());
foreach (var item in aList)
{
Person p = item as Person;
Console.WriteLine(p.Name + " " + p.Age);
}
这样,如果需求变化了,我只需在声明一个类,实现IComparer接口即可。然后调用集合的Sort方法时,将类new出来的对象放进去就好了。
好了,关于ArrayList就说这么多,如果有大神要补充的,请直接回复哈。共同进步!
C#集合之ArrayList的更多相关文章
- C#语言基础——集合(ArrayList集合)
集合及特殊集合 集合的基本信息: System.Collections 命名空间包含接口和类,这些接口和类定义各种对象(如列表.队列.位数组.哈希表和字典)的集合.System.Collections ...
- Java基础知识强化之集合框架笔记64:Map集合之ArrayList嵌套HashMap
1. ArrayList集合嵌套HashMap集合并遍历. 需求: 假设ArrayList集合的元素是HashMap.有3个. 每一个HashMap集合的键和值都是字 ...
- C#重的数组、集合(ArrayList)、泛型集合(list<T>)三者比较及扩展延伸……
本来我只想总结下数组.集合(ArrayList).泛型集合(list<T>)三者的比较的,可以一写下来要扩展的知识点有点多了,只能写一个小的知识点列表了如下: 1.数组.集合(ArrayL ...
- 集合框架-ArrayList,Vector,Linkedlist
// ClassCastException 报错,注意,千万要搞清楚类型 * Vector的特有功能: * 1:添加功能 * public void addElement(Object obj) -- ...
- 转:C#常用的集合类型(ArrayList类、Stack类、Queue类、Hashtable类、Sort)
C#常用的集合类型(ArrayList类.Stack类.Queue类.Hashtable类.Sort) .ArrayList类 ArrayList类主要用于对一个数组中的元素进行各种处理.在Array ...
- C#基础课程之四集合(ArrayList、List<泛型>)
list泛型的使用 ArrayList list = new ArrayList(); ArrayList list = ); //可变数组 list.Add("我"); //Ad ...
- Java基础-集合框架-ArrayList源码分析
一.JDK中ArrayList是如何实现的 1.先看下ArrayList从上而下的层次图: 说明: 从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList. ...
- C#中数组、集合(ArrayList)、泛型集合List<T>、字典(dictionary<TKey,TValue>)全面对比
C#中数组.集合(ArrayList).泛型集合List<T>.字典(dictionary<TKey,TValue>)全面对比 为什么把这4个东西放在一起来说,因为c#中的这4 ...
- 从源码看Java集合之ArrayList
Java集合之ArrayList - 吃透增删查改 从源码看初始化以及增删查改,学习ArrayList. 先来看下ArrayList定义的几个属性: private static final int ...
随机推荐
- MySQL Workbench 导出数据库脚本(图文)
1.如下图红框所示,在Server Administration那里,点击"New Server Instance" 2.如下图所示,如果是连接本地数据库,则选localhost, ...
- STL学习系列二:Vector容器
1.Vector容器简介 vector是将元素置于一个动态数组中加以管理的容器. vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法,这个等下会详讲). vector尾部添 ...
- Cocos2d-x 重写draw方法绘制直线等图形时被遮挡覆盖问题的一种解决方案
最近在学习过程cocos2dx的过程中需要使用到绘制直线的功能,所以我就采用了引擎中 ccDrawLine 方法,然后重写 draw 方法,在该方法中绘制直线. 但是出现了一个问题,那就是绘制的图形被 ...
- java泛型 8 泛型的内部原理:类型擦除以及类型擦除带来的问题
参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首 ...
- Css基础-id选择器
id 选择器以#来定义 <p id="pid">Hello css</p> #pid { color:red; } <div id="div ...
- Qt 经典出错信息之”Basic XLib functionality test failed!”(Z..z..)
此完整出错信息是在./configure阶段 Basic XLib functionality test failed! You might need to modify the include an ...
- utf8乱码解决方案[适合tomcat部署的jsp应用]
转:http://blog.csdn.net/cn_gaowei/article/details/6673539 1. java类: CharacterEncodingFilter im ...
- IOS 横屏中添加UIImagePickerController获取系统图片
今天写ipad的项目,然后需要调用系统相册选择图片,然后用了UIImagePickerController ,崩溃了,后来查了一下,UIImagePickerController只支持竖屏,但是... ...
- PHP函数ip2long转换IP时数值太大产生负数的解决办法
有两种办法: 1. bindec( decbin($long)) 利用bindec和decbin两个函数转换一次就没有问题了 我一直在用上面的方法,但是在升级到PHP7以后就不起作用了(因为最近只进 ...
- 【《Objective-C基础教程 》笔记ch05】(六)OC中的复合机制Composition
1.复合通过包括作为实例变量的的对象指针实现的. @interface Unicycle : NSObject { Pedal*pedal; ...