一、数组

数组在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单。

1、一维数组

声明一个数组:
int[] array = new int[5];

 

初始化一个数组:
int[] array1 = new int[5] { 1, 3, 5, 7, 9 }; //定长


声明并初始化:
int[] array2 = { 1, 3, 5, 7, 9 }; //不定长

 


2、多维数组
int[,] numbers = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} };

但是数组存在一些不足的地方。在数组的两个数据间插入数据是很麻烦的,而且在声明数组的时候必须指定数组的长度,数组的长度过长,会造成内存浪费,过短会造成数据溢出的错误。如果在声明数组时我们不清楚数组的长度,就会变得很麻烦。

    针对数组的这些缺点,.net中最先提供了ArrayList对象来克服这些缺点。 

 

二、ArrayList

ArrayList是命名空间System.Collections下的一部分,在使用该类时必须进行引用,同时继承了IList接口,提供了数据存储和检索。ArrayList对象的大小是按照其中存储的数据来动态扩充与收缩的。所以,在声明ArrayList对象时并不需要指定它的长度。

 

ArrayList list1 = new ArrayList();  
  
//新增数据  
list1.Add("cde");  
list1.Add(5678);  
  
//修改数据  
list[2] = 34;  
  
//移除数据  
list.RemoveAt(0);  
  
//插入数据  
list.Insert(0, "qwe");  

 

我们从上面的例子看,在List中,我们不仅插入了字符串cde,而且插入了数字5678。这样在ArrayList中插入不同类型的数据是允许的。因为ArrayList会把所有插入其中的数据当作为object类型来处理,在我们使用ArrayList处理数据时,很可能会报类型不匹配的错误,也就是ArrayList不是类型安全的。在存储或检索值类型时通常发生装箱和取消装箱操作,带来很大的性能耗损。

补充:数组扩容
   这是对ArrayList效率影响比较大的一个因素。

   每当执行Add、AddRange、Insert、InsertRange等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量的两倍来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。

例1:比如,一个可能有200个元素的数据动态添加到一个以默认16个元素大小创建的ArrayList中,将会经过:

16*2*2*2*2 = 256

四次的扩容才会满足最终的要求,那么如果一开始就以:

ArrayList List = new ArrayList( 210 ); 
的方式创建ArrayList,不仅会减少4次数组创建和Copy的操作,还会减少内存使用。

例2:预计有30个元素而创建了一个ArrayList:

ArrayList List = new ArrayList(30); 
在过程中,加入了31个元素,那么数组会扩充到60个元素的大小,而这时候不会有新的元素再增加进来,而且有没有调用TrimSize方法,那么就有1次扩容的操作,并且浪费了29个元素大小的空间。如果这时候,用:

ArrayList List = new ArrayList(40); 
那么一切都解决了。

所以说,正确的预估可能的元素,并且在适当的时候调用TrimSize方法是提高ArrayList使用效率的重要途径。


三、List

  因为ArrayList存在不安全类型与装箱拆箱的缺点,所以出现了泛型的概念。List类是ArrayList类的泛型等效类,它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。
List<string> list = new List<string>();  //新增数据  

list.Add(“abc”);  //修改数据  

list[0] = “def”;  //移除数据  

list.RemoveAt(0);  

四、LinkedList

然而数组和数组列表都有一个重大的缺陷,这就是从数组的中间位置删除一个元素需要付出很大的代价,其原因是数组中处于被删除元素之后的所有元素都要向数组的前端移动。在数组的中间的位置插入一个元素也是如此。如下图:

 

这个问题就靠LinkedList(链表)来解决。链表将每个对象存放在独立的节点中,每个节点还存放着序列中上一个节点的引用和下一个节点的引用,如下图:

这样,从链表中间删除一个元素是很轻松的操作,即需要对呗删除元素附近的节点更新一下即可,如下图:

List<String> names=new LinkedList<>();
names.add("Amy");
names.add("Bob");

 

 

 

总结:

    数组的容量是固定的,只能一次获取或设置一个元素的值,而ArrayList或List<T>的容量可根据需要自动扩充、修改、删除或插入数据。

    数组可以具有多个维度,而 ArrayList或 List< T> 始终只具有一个维度。但是,可以轻松创建数组列表或列表的列表。特定类型(Object 除外)的数组 的性能优于 ArrayList的性能。 这是因为 ArrayList的元素属于 Object 类型;所以在存储或检索值类型时通常发生装箱和取消装箱操作。不过,在不需要重新分配时(即最初的容量十分接近列表的最大容量),List< T> 的性能与同类型的数组十分相近。

    在决定使用 List<T> 还是使用ArrayList 类(两者具有类似的功能)时,记住List<T> 类在大多数情况下执行得更好并且是类型安全的。如果对List< T> 类的类型T 使用引用类型,则两个类的行为是完全相同的。但是,如果对类型T使用值类型,则需要考虑实现和装箱问题。

   ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

   对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

   对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

 

 

posted @ 2016-08-10 21:33 后知然后觉 阅读(37855) 评论(4) 推荐(3) 编辑
摘要: 接口1.接口只提供方法规约,不提供方法体;2.接口中的方法不能用关键字修饰;3.接口里不能有接口和变量;4.接口里的方法在子类中必须全部实现;5.接口可以实现多重继承;抽象类1.抽象类可以从接口继承;2.抽象类中的实体方法在子类中不可以重写,只可以被引用;3.抽象类中的抽象方法不可以有方法体,抽象类 阅读全文
posted @ 2016-08-07 18:06 后知然后觉 阅读(2630) 评论(2) 推荐(2) 编辑
摘要: 抽象类定义:它的作用就是产生子类的同时给于子类一些特定的属性和方法。abstract修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用abstract修饰符以指示某个类只能是其他类的父类。标记为抽象或包含在抽象类中的成员必须通过从抽象类的子类来实现。特性:1.抽象类不能被实例化;2.抽 阅读全文
posted @ 2016-08-07 18:00 后知然后觉 阅读(837) 评论(0) 推荐(1) 编辑
摘要: 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,就在于函数内部可以直接读取全 阅读全文
posted @ 2016-07-21 21:05 后知然后觉 阅读(507) 评论(2) 推荐(0) 编辑
摘要: 首先介绍下Javascript的函数作用域的概念,然后了解下什么是作用域和声明提前,最后通过一个例子剖析Javascript的作用域链。 1.变量的作用域 稍微有些编程背景的都知道,变量的作用域分为两种: 全局变量 和 局部变量 。 Javascript是一门 弱类型语言 。所有的变量声明都是通过v 阅读全文
posted @ 2016-07-20 21:15 后知然后觉 阅读(6221) 评论(1) 推荐(0) 编辑
摘要: 一,游标是什么? 游标是一段私有的SQL工作区,也就是一段内存区域,用于暂时存放受SQL语句影响到的数据。通俗理解就是将受影响的数据暂时放到了一个内存区域的虚表中,而这个虚表就是游标。 二,作用是什么? 1,大家都知道数据库中的事物可以回滚,而游标在其中起着非常重要的作用,由于对数据库的操作我们会暂 阅读全文
posted @ 2016-07-20 20:20 后知然后觉 阅读(576) 评论(0) 推荐(0) 编辑
摘要: 一、存储过程与函数的区别: 1.一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。 2.对于存储过程来说可以返回参数(output),而函数只能返回值或者表对象。 3.存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因 阅读全文
posted @ 2016-07-20 20:12 后知然后觉 阅读(2901) 评论(0) 推荐(0) 编辑
摘要: 一、索引的概述 1、概念: 数据库索引是对数据表中一个或多个列的值进行排序的结构,就像一本书的目录一样,索引提供了在行中快速查询特定行的能力。 2、优缺点: 2.1优点: 1、大大加快搜索数据的速度,这是引入索引的主要原因. 2、创建唯一性索引,保证数据库表中每一行数据的唯一性. 3、加速表与表之间 阅读全文
posted @ 2016-07-14 21:06 后知然后觉 阅读(259) 评论(0) 推荐(0) 编辑
摘要: 指定临时命名的结果集,这些结果集称为公用表表达式 (CTE)。公用表表达式可以包括对自身的引用。这种表达式称为递归公用表表达式。 对于递归公用表达式来说,实现原理也是相同的,同样需要在语句中定义两部分: 基本语句 递归语句 在SQL这两部分通过UNION ALL连接结果集进行返回: 使用CTE准则 阅读全文
posted @ 2016-06-28 12:44 后知然后觉 阅读(1060) 评论(0) 推荐(0) 编辑
摘要: 创建表scores 一、传统的行列转换 纵表转横表 我们要转成的横表是这样子的: 既然这个表只有两列,那么可以根据姓名进行分组。先把姓名拼凑出来,后面的分数我们再想办法。 结果: 分析: 这里符合我们需求的 case 语句就登场了。它和c#中switch-case 作用一样。 sql case 语句 阅读全文
posted @ 2016-06-28 08:18 后知然后觉 阅读(36151) 评论(1) 推荐(3) 编辑
点击右上角即可分享
微信分享提示