问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

怎么遍历非泛型集合,集合里边的类型都不一样Java

发布网友 发布时间:2022-04-25 01:29

我来回答

1个回答

热心网友 时间:2023-08-28 01:13

软件开发过程中,不可避免会用到集合,C#中的集合表现为数组和若干集合类。不管是数组还是集合类,它们都有各自的优缺点。如何使用好集合是我们在开发过程中必须掌握的技巧。不要小看这些技巧,一旦在开发中使用了错误的集合或针对集合的方法,应用程序将会背离你的预想而运行。

建议20:使用泛型集合代替非泛型集合

在建议1中我们知道,如果要让代码高效运行,应该尽量避免装箱和拆箱,以及尽量减少转型。很遗憾,在微软提供给我们的第一代集合类型中没有做到这一点,下面我们看ArrayList这个类的使用情况:
ArrayList al=new ArrayList(); al.Add(0); al.Add(1); al.Add("mike"); foreach (var item in al) { Console.WriteLine(item); }
上面这段代码充分演示了我们可以将程序写得多么糟糕。

首先,ArrayList的Add方法接受一个object参数,所以al.Add(1)首先会完成一次装箱;其次,在foreach循环中,待遍历到它时,又将完成一次拆箱。

在这段代码中,整形和字符串作为值类型和引用类型,都会先被隐式地强制转型为object,然后在foreach循环中又被转型回来。

同时,这段代码也是非类型安全的:我们然ArrayList同时存储了整型和字符串,但是缺少编译时的类型检查。虽然有时候需要有意这样去实现,但是更多的时候,应该尽量避免。缺少类型检查,在运行时会带来隐含的Bug。集合类ArrayList如果进行如下所示的运算,就会抛出一个IvalidCastException:
ArrayList al=new ArrayList(); al.Add(0); al.Add(1); al.Add("mike"); int t = 0; foreach (int item in al) { t += item; }
ArrayList同时还提供了一个带ICollection参数的构造方法,可以直接接收数组,如下所示:
var intArr = new int[] {0, 1, 2, 3}; ArrayList al=new ArrayList(intArr);

该方法内部实现一样糟糕,如下所示(构造方法内部最终调用了下面的InsertRange方法):
public virtual void InsertRange(int index, ICollection c) { if (c == null) { throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection")); } if ((index < 0) || (index > this._size)) { throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); } int count = c.Count; if (count > 0) { this.EnsureCapacity(this._size + count); if (index < this._size) { Array.Copy(this._items, index, this._items, index + count, this._size - index); } object[] array = new object[count]; c.CopyTo(array, 0); array.CopyTo(this._items, index); this._size += count; this._version++; } }
概括来讲,如果对大型集合进行循环访问、转型或装箱和拆箱操作,使用ArrayList这样的传统集合对效率影响会非常大。鉴于此,微软提供了对泛型的支持。泛型使用一对<>括号将实际类型括起来,然后编译器和运行时会完成剩余的工作。微软也不建议大家使用ArrayList这样的类型了,转而建议使用它们的泛型实现,如List<T>。

注意,非泛型集合在System.Collections命名空间下,对应的泛型集合则在System.Collections.Generic命名空间下。

建议一开始的那段代码的泛型实现为:
List<int> intList = new List<int>(); intList.Add(1); intList.Add(2); //intList.Add("mike"); foreach (var item in intList) { Console.WriteLine(item); }
代码中被注释的那一行不会被编译通过,因为“mike"不是整型,这里就体现了类型安全的特点。

下面比较了非泛型集合和泛型集合在运行中的效率:
static void Main(string[] args) { Console.WriteLine("开始测试ArrayList:"); TestBegin(); TestArrayList(); TestEnd(); Console.WriteLine("开始测试List<T>:"); TestBegin(); TestGenericList(); TestEnd(); } static int collectionCount = 0; static Stopwatch watch = null; static int testCount = 10000000; static void TestBegin() { GC.Collect(); //强制对所有代码进行即时垃圾回收 GC.WaitForPendingFinalizers(); //挂起线程,执行终结器队列中的终结器(即析构方法) GC.Collect(); //再次对所有代码进行垃圾回收,主要包括从终结器队列中出来的对象 collectionCount = GC.CollectionCount(0); //返回在0代码中执行的垃圾回收次数 watch = new Stopwatch(); watch.Start(); } static void TestEnd() { watch.Stop(); Console.WriteLine("耗时:" + watch.ElapsedMilliseconds.ToString()); Console.WriteLine("垃圾回收次数:" + (GC.CollectionCount(0) - collectionCount)); } static void TestArrayList() { ArrayList al = new ArrayList(); int temp = 0; for (int i = 0; i < testCount; i++) { al.Add(i); temp = (int)al[i]; } al = null; } static void TestGenericList() { List<int> listT = new List<int>(); int temp = 0; for (int i = 0; i < testCount; i++) { listT.Add(i); temp = listT[i]; } listT = null; }
输出为:

开始测试ArrayList:

耗时:2375

垃圾回收次数:26

开始测试List<T>:

耗时:220

垃圾回收次数:5
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
什么时间试排卵纸最佳 排卵第十天排卵试纸弱阳怎么回事 手机app下载课后帮 课后帮点击了家长怎么改成学生的 课后帮绑定学生后还能绑定家长吗 课后帮怎么注册 课后帮注册教程 癫痫急救的正确方法 癫痫持续状态的抢救要点 小儿癫痫发作的急救措施 癫痫病急救常识有哪些要点 重点讲解系统使用了哪些泛型集合 谁能解释下“GUESS COLLECTION”是什么样的表?有中文名么? 如何找到真正N厂手表的一手渠道?有人推荐noobwatchfk ,也有人推荐watchgc GC手表的历史及中国的专营店 手表 日期坏了维修多少 时度手表调不了日历了,长沙哪里可以维修? 广州在哪里可以维修伯爵手表?我的手表每天走慢好几分钟。日历也调不了,什么原因? 欧米茄机械表日历框出问题了,不知道在广州哪里可以维修? 机械表维修日历需要多少钱?师父说要全部拆开需要80贵吗? 机械表日期坏了,能修好吗? 手表调日期坏了怎么办?多钱能修?维修麻烦吗?淘宝买的。 手表日历不太正,修表的能修吗 西铁城手表日历坏了修一下需要多少钱?盐城市哪里有修的好的店?谢谢 西铁城手表日历坏了修一下需要多少钱?盐城市哪里修的好? 温州名表维修,我的朗格手表的万年历坏了怎么办? 手表日历不对如何处理? 手表上的日历坏了怎么办? 唱歌怎样发高音? 手表日历不走了怎么调整? 怎么唱高音? 沛纳海哪款仿得最好 请高手们帮忙啊 翻译 C#实现注册表监控 求20个一般过去式的英文句子 热更新真的那么重要吗 关于WII实机无法运行任天堂明星大乱斗X,有大神知道怎么破吗 高二外研英语周报第9期答案 一个DNA分子中有一个位点的GC被AT所替换,导致翻译过程中这一位点出现终止密码子,我认为有终止密码子可能导 谁知道python视频教程的下载网,要可下载的 森田泽之是谁? PSP极品飞车10第一关怎么过? C#编写的WinForm程序,运行一段时间后越来越卡,怎么办? 麦饭石锅内都是粗糙的吗 珐琅锅和麦饭石哪个不好 麦板石种类 韩国尚膳厨的麦饭石锅,可能是由于炒菜时火大,锅内部中间段发黄,洗不掉,有什么办法去掉呢?求助大神! 烧开水的时候放入麦饭石可以起到净化水中氯气的作用吗 鱼缸里放入麦饭石好不好. 玺锐嘉麦饭石真空微压炒锅多少钱 如何软化加湿器里的水质