关闭

数组、ArrayList、List、LinkedList的区别

320人阅读 评论(0) 收藏 举报
分类:

转  https://www.cnblogs.com/janneystory/p/5758958.html


一、数组

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

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要移动数据。



0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

java集合框架05——ArrayList和LinkedList的区别

前面已经学习完了List部分的源码,主要是ArrayList和LinkedList两部分内容,这一节主要总结下List部分的内容。 List概括 先来回顾一下List在Collection中的的框架图: 从图中我们可以看出: 1. List是一个接口,它继承与Collection接口,代表有序的...
  • eson_15
  • eson_15
  • 2016-04-13 20:39
  • 9214

数组、ArrayList、LinkedList查询及遍历性能分析 .

最近研究spring框架时,发现它在存储以查询和遍历居多的数据时采用的数组,而不是现在很多书中推荐的List。并且之前也发现tomcat在实现自己的service和connector时,也是多采用数组的方式。虽然之前也大概了解到list,特别是linkedList和数组在数据查询上确实有差距,但是没...
  • mafly008
  • mafly008
  • 2013-10-10 12:33
  • 1794

Java进阶(四十六)简述ArrayList、Vector与LinkedList的异同点

简述ArrayList、Vector与LinkedList的异同点  Collection类的继承图如下:   从图中可以看出,LinkedList与ArrayList、ArrayDeque这三者都实现了List接口.所有使用方式也很相似,主要区别在于因为实现方式的不同,所以对不同的操作具有不同的...
  • sunhuaqiang1
  • sunhuaqiang1
  • 2016-10-08 20:27
  • 43856

ArrayList和LinkedList底层实现的区别

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。     2.对于随机访问get和set,ArrayList优于LinkedList,因为ArrayList可以随机定位,而LinkedList要移动指针一步一步的移动到...
  • u013673242
  • u013673242
  • 2015-01-29 15:37
  • 8372

小谈面试时面试官为什么问ArrayList,LinkedList与List的不同

当你做为一个技术面试官面试应聘者时,你总是想尝试能全面了解这个面试者的方方面面。技术,背景,性格都是被重点关注的。面试官想在短暂的面试过程中多了解应聘者,那就要有明确的目的性。但是一般面试官不会只是简单问你某某知识点,每个面试题目的背后都有着深意。下面我以list的面试题目来小小剖析一下。 当面试官...
  • yuyanjun123
  • yuyanjun123
  • 2016-06-22 16:29
  • 384

ArrayList和LinkedList底层实现与理解

78、集合中存放的依然是对象的引用而不是对象的本身。 79、ArrayList底层采用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个长度为10的Object类型数组。 80、如果增加的元素个数超过了10个,那么ArrayList底层会新生成一个数组,长度为原数...
  • u011638419
  • u011638419
  • 2013-09-22 17:20
  • 2627

数组的特点,数组的使用,链表的特点,set和list的区别,arrayList,linkedList,的常用方法,set,hashset,

数组的特点: 数组的长度一旦定义则不能改变 数组中的元素都有整数索引 数组只能存储同一类型的元素 数组即可以存储基本数据类型,又可以存储引用数据类型 数组的使用: 获取元素。通过索引获取,arr[2]; 添加元素(在元素3后面添加一个新元素8):要先创建新的数组,长度为原先的数组长度...
  • boss_way
  • boss_way
  • 2017-10-26 20:57
  • 152

java源码分析之集合框架 ArrayList和LinkedList的区别05

List概括 先来回顾一下List在Collection中的的框架图: 从图中我们可以看出: 1. List是一个接口,它继承与Collection接口,代表有序的队列。 2. AbstractList是一个抽象类,它继承于AbstractCo...
  • wangnanwlw
  • wangnanwlw
  • 2016-08-17 13:35
  • 570

ArrayList 和 LinkedList 和Vector使用上有什么区别?实现上有什么区别?

ArrayList 和 Vector 使用上有什么区别?实现上有什么区别?Vector和ArrayList在使用上非常相似,都可用来表示一组数量可变的对象应用的集合,并且可以随机地访问其中的元素。 1 Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe...
  • u012373815
  • u012373815
  • 2015-11-30 10:19
  • 1274

Vector,ArrayList,LinkedList 的区别是什么?

简要概括: 1、Vector、ArrayList都是以类似数组的形式存储在内存中,LinkedList则以链表的形式进行存储。 2、List中的元素有序、允许有重复的元素,Set中的元素无序、不允许有重复元素。 3、Vector线程同步,ArrayList、LinkedList线程不同步。 ...
  • xuanjiewu
  • xuanjiewu
  • 2016-01-26 10:21
  • 981
    个人资料
    • 访问:34176次
    • 积分:943
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:53篇
    • 译文:37篇
    • 评论:0条
    文章分类