java 集合 之 链表和线性表以及ArrayList的各方法的介绍及示例 及 ArrayList与LinkedList的区别分析 及 ArrayList与Array(数组)的区别

来源:互联网 发布:电影极度寒冷知乎 编辑:程序博客网 时间:2024/05/20 05:25
ArrayList  数组列表LinkedList 链表Array   数组set集合ArrayDeque    双端队列map 图SequentialList   顺序表Queue  队列
package NEW_DATE_SEQUENCE_PACKAGE;import java.util.LinkedList;import java.util.ListIterator;/** * * @author cmx */public class J_8_31_1 {    public static void main(String[] args)    {        LinkedList<String> list=new LinkedList<>();        list.add("a");        list.add("b");        list.add("c");        ListIterator list3=list.listIterator(0);        String get3=list.get(1);        list3.next();        String test_2_move=list3.next().toString();        System.out.println("what >       "+test_2_move);        list3.set("hhhhh");        System.out.println(list.toString());        list.listIterator(0);       int i =list.listIterator(0).nextIndex();        String a=list.get(0);        System.out.println(a);        String b=list.listIterator(1).previous();        System.out.println(b);        System.out.println(i);        ListIterator<String>  list1=list.listIterator(1);        String c=list1.next();        System.out.println(c);    }}/** * run:what >       b[a, hhhhh, c]aa0hhhhh成功构建 (总时间: 0 秒) */

一般大家都知道ArrayList和LinkedList的大致区别: 

     1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
     2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
     3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 

ArrayList和LinkedList是两个集合类,用于存储一系列的对象引用(references)。例如我们可以用ArrayList来存储一系列的String或者Integer。那么ArrayList和LinkedList在性能上有什么差别呢?什么时候应该用ArrayList什么时候又该用LinkedList呢?


一.时间复杂度 
首先一点关键的是,ArrayList的内部实现是基于基础的对象数组的,因此,它使用get方法访问列表中的任意一个元素时(random access),它的速度要比LinkedList快。LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端。对LinkedList而言,访问列表中的某个指定元素没有更快的方法了。 
假设我们有一个很大的列表,它里面的元素已经排好序了,这个列表可能是ArrayList类型的也可能是LinkedList类型的,现在我们对这个列表来进行二分查找(binary search),比较列表是ArrayList和LinkedList时的查询速度,看下面的程序: 

Java代码  收藏代码
  1. package com.mangocity.test;   
  2. import java.util.LinkedList;   
  3. import java.util.List;   
  4. import java.util.Random;   
  5. import java.util.ArrayList;   
  6. import java.util.Arrays;   
  7. import java.util.Collections;   
  8. public class TestList …{   
  9.      public static final int N=50000;   
  10.   
  11.      public static List values;   
  12.   
  13.      static…{   
  14.          Integer vals[]=new Integer[N];   
  15.   
  16.          Random r=new Random();   
  17.   
  18.          for(int i=0,currval=0;i<N;i++)…{   
  19.              vals=new Integer(currval);   
  20.              currval+=r.nextInt(100)+1;   
  21.          }   
  22.   
  23.          values=Arrays.asList(vals);   
  24.      }   
  25.   
  26.      static long timeList(List lst)…{   
  27.          long start=System.currentTimeMillis();   
  28.          for(int i=0;i<N;i++)…{   
  29.              int index=Collections.binarySearch(lst, values.get(i));   
  30.              if(index!=i)   
  31.                  System.out.println(”***错误***”);   
  32.          }   
  33.          return System.currentTimeMillis()-start;   
  34.      }   
  35.      public static void main(String args[])…{   
  36.          System.out.println(”ArrayList消耗时间:”+timeList(new ArrayList(values)));   
  37.          System.out.println(”LinkedList消耗时间:”+timeList(new LinkedList(values)));   
  38.      }   
  39. }   

我得到的输出是:ArrayList消耗时间:15 

                 LinkedList消耗时间:2596 

这个结果不是固定的,但是基本上ArrayList的时间要明显小于LinkedList的时间。因此在这种情况下不宜用LinkedList。二分查找法使用的随机访问(random access)策略,而LinkedList是不支持快速的随机访问的。对一个LinkedList做随机访问所消耗的时间与这个list的大小是成比例的。而相应的,在ArrayList中进行随机访问所消耗的时间是固定的。 

这是否表明ArrayList总是比LinkedList性能要好呢?这并不一定,在某些情况下LinkedList的表现要优于ArrayList,有些算法在LinkedList中实现时效率更高。比方说,利用Collections.reverse方法对列表进行反转时,其性能就要好些。 

看这样一个例子,假如我们有一个列表,要对其进行大量的插入和删除操作,在这种情况下LinkedList就是一个较好的选择。请看如下一个极端的例子,我们重复的在一个列表的开端插入一个元素: 

Java代码  收藏代码
  1. package com.mangocity.test;   
  2.   
  3. import java.util.*;   
  4. public class ListDemo {   
  5.      static final int N=50000;   
  6.      static long timeList(List list){   
  7.      long start=System.currentTimeMillis();   
  8.      Object o = new Object();   
  9.      for(int i=0;i<N;i++)   
  10.          list.add(0, o);   
  11.      return System.currentTimeMillis()-start;   
  12.      }   
  13.      public static void main(String[] args) {   
  14.          System.out.println(”ArrayList耗时:”+timeList(new ArrayList()));   
  15.          System.out.println(”LinkedList耗时:”+timeList(new LinkedList()));   
  16.      }   
  17. }   

 这时我的输出结果是:ArrayList耗时:2463

                                                LinkedList耗时:15 

这和前面一个例子的结果截然相反,当一个元素被加到ArrayList的最开端时,所有已经存在的元素都会后移,这就意味着数据移动和复制上的开销。相反的,将一个元素加到LinkedList的最开端只是简单的未这个元素分配一个记录,然后调整两个连接。在LinkedList的开端增加一个元素的开销是固定的,而在ArrayList的开端增加一个元素的开销是与ArrayList的大小成比例的。


二.空间复杂度 
在LinkedList中有一个私有的内部类,定义如下:

Java代码  收藏代码
  1. private static class Entry {   
  2.          Object element;   
  3.          Entry next;   
  4.          Entry previous;   
  5.      }   

每个Entry对象reference列表中的一个元素,同时还有在LinkedList中它的上一个元素和下一个元素。一个有1000个元素的LinkedList对象将有1000个链接在一起的Entry对象,每个对象都对应于列表中的一个元素。这样的话,在一个LinkedList结构中将有一个很大的空间开销,因为它要存储这1000个Entity对象的相关信息。 
ArrayList使用一个内置的数组来存储元素,这个数组的起始容量是10.当数组需要增长时,新的容量按如下公式获得:新容量=(旧容量*3)/2+1,也就是说每一次容量大概会增长50%。这就意味着,如果你有一个包含大量元素的ArrayList对象,那么最终将有很大的空间会被浪费掉,这个浪费是由ArrayList的工作方式本身造成的。如果没有足够的空间来存放新的元素,数组将不得不被重新进行分配以便能够增加新的元素。对数组进行重新分配,将会导致性能急剧下降。如果我们知道一个ArrayList将会有多少个元素,我们可以通过构造方法来指定容量。我们还可以通过trimToSize方法在ArrayList分配完毕之后去掉浪费掉的空
间。


三.总结 
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下: 
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。


2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。


3.LinkedList不支持高效的随机元素访问。


4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间


可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。



ArrayList(动态数组列表)与Array( 数组)的区别

1. Array类型的变量在声明的同时必须进行实例化(至少得初始化数组的大小),而ArrayList可以只是先声明。
2. Array只能存储同构的对象,而ArrayList可以存储异构的对象。
同构的对象是指类型相同的对象,若声明为int[]的数组就只能存放整形数据,
string[]只能存放字符型数据,但声明为object[]的数组除外。
而ArrayList可以存放任何不同类型的数据(因为它里面存放的都是被装箱了的Object型对象,实际上ArrayList内部就是使用
object[] _items;这样一个私有字段来封装对象的)

3 在CLR托管对中的存放方式
Array是始终是连续存放的,而ArrayList的存放不一定连续。

4 初始化大小
Array对象的初始化必须只定指定大小,且创建后的数组大小是固定的,
而ArrayList的大小可以动态指定,其大小可以在初始化时指定,也可以不指定,也就是说该对象的空间可以任意增加。

5 Array不能够随意添加和删除其中的项,而ArrayList可以在任意位置插入和删除项。


Array和ArrayList的相似点
1 都具有索引(index),即可以通过index来直接获取和修改任意项。
2 他们所创建的对象都放在托管堆中。
3 都能够对自身进行枚举(因为都实现了IEnumerable接口)。

ArrayList的一些特性

ArrayList的capacity属性值会随ArrayList中的项的实际大小来发生改变

通过ArrayList类的TrimToResize()方法可以将ArrayList实例中的空项去除以压缩体积。
在C#2.0中,建议大家尽量使用范型版的ArrayList,即System.Collection.Generics命名空间下的List<T>,
这样不但保证了类型安全,而且由于没有了装箱和拆箱的过程,从而提高了对象处理的效率。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 刺猴冷冻后起泡怎么办 隔壁太吵怎么办阴招 楼上有小孩太吵怎么办 捷达小水管睹了怎么办 楼房下水管冻了怎么办 一楼地面很潮湿怎么办 新房子地面有裂缝怎么办 地砖下面的下水管漏水怎么办 速冻饺子冻在一起了怎么办 牛排泡水解冻了怎么办 饺子都粘一起了怎么办 把桃子放冷冻了怎么办 抖音小视频连不上网怎么办 网络视频连不上网怎么办 苹果8视频不清晰怎么办 乳疮腐烂还臭怎么办 冰箱肉腐烂很臭怎么办 指环扣松了怎么办视频 奇迹mu端游杀人了怎么办 奇迹最强者号找不着了怎么办 v领地退不了押金怎么办 全民奇迹sf钻石变负数怎么办 电脑上的新建没有了怎么办 火车上行李箱砸人怎么办 违建拆除后怎么办房产证 外地车遇到限号怎么办 双号限行 违了怎么办 下高速当地限行怎么办 下高速发现限号怎么办 下高速正好限号怎么办 限号不让下高速怎么办 我的歌没有编曲怎么办 奇迹暖暖以前的账号怎么办 孕妇误吃桃胶了怎么办? 孕4个月吃了桃胶怎么办 刚怀孕吃了桃胶怎么办 额头被打了个包怎么办 裤子被84掉颜色怎么办 高中生晚上偷家里电脑上网怎么办 住高层睡不好觉怎么办 水瓶座如果恨我们了该怎么办