Java中ArrayList和LinkedList之间的区别_动力节点Java学院整理

一、ArrayList

ArrayList是一个可以处理变长数组的类型,这里不局限于“数”组,ArrayList是一个泛型类,可以存放任意类型的对象。顾名思义,ArrayList是一个数组列表,因此其内部是使用一个数组来存放对象的,因为Object是一切类型的父类,因而ArrayList内部是有一个Object类型的数组类存放对象。ArrayList类常用的方法有add()、clear()、get()、indexOf()、remove()、sort()、toArray()、toString()等等,同时ArrayList内部有一个私有类实现Iterator接口,因此可以使用iterator()方法得到ArrayList的迭代器,同时,还有一个私有类实现了ListIterator接口,因此ArrayList也可以调用listIterator()方法得到ListIterator迭代器。
由于ArrayList是依靠数组来存放对象的,只不过封装起来了而已,因此其一些查找方法的效率都是O(n),跟普通的数组效率差不多,只不过这个ArrayList是一个可变”数组“,并且可以存放一切指定的对象。
另外,由于ArrayList的所有方法都是默认在单一线程下进行的,因此ArrayList不具有线程安全性。若想在多线程下使用,应该使用Colletions类中的静态方法synchronizedList()对ArrayList进行调用即可。

二、LinkedList

LinkedList可以看做为一个双向链表,所有的操作都可以认为是一个双向链表的操作,因为它实现了Deque接口和List接口。同样,LinkedList也是线程不安全的,如果在并发环境下使用它,同样用Colletions类中的静态方法synchronizedList()对LinkedList进行调用即可。

在LinkedList的内部实现中,并不是用普通的数组来存放数据的,而是使用结点<Node>来存放数据的,有一个指向链表头的结点first和一个指向链表尾的结点last。不同于ArrayList只能在数组末尾添加数据,LinkList可以很方便在链表头或者链表尾插入数据,或者在指定结点前后插入数据,还提供了取走链表头或链表尾的结点,或取走中间某个结点,还可以查询某个结点是否存在。add()方法默认在链表尾部插入数据。总之,LinkedList提供了大量方便的操作方法,并且它的插入或增加等方法的效率明显高于ArrayList类型,但是查询的效率要低一点,因为它是一个双向链表。

因此,LinkedList与ArrayList最大的区别是LinkedList更加灵活,并且部分方法的效率比ArrayList对应方法的效率要高很多,对于数据频繁出入的情况下,并且要求操作要足够灵活,建议使用LinkedList;对于数组变动不大,主要是用来查询的情况下,可以使用ArrayList。

import java.util.* ;
public class ListDemo01{
  public static void main(String args[]){
    List<Integer> li = new LinkedList<Integer>() ;
    long startTime = System.currentTimeMillis() ;
    for(int i=0;i<1000000;i++){
      li.add(0,i) ;        //print : 803
      //li.add(i) ;        //print : 790
    }
    long endTime = System.currentTimeMillis() ;
    System.out.println(endTime-startTime) ;
  }
}

下面的代码得不出结果速度太慢

import java.util.* ;
public class ListDemo01{
  public static void main(String args[]){
    List<Integer> li = new LinkedList<Integer>() ;
    for(int i=0;i<1000000;i++){
      li.add(0,i) ;        //print : 803
      //li.add(i) ;        //print : 790
    }
    long startTime = System.currentTimeMillis() ;
    for(int i=0;i<1000000;i++){
      li.get(i) ;
    }
    long endTime = System.currentTimeMillis() ;
    System.out.println(endTime-startTime) ;
  }
} 

下面化成ArrayList速度就超快

import java.util.* ;
public class ListDemo01{
  public static void main(String args[]){
    List<Integer> li = new ArrayList<Integer>() ;
    for(int i=0;i<1000000;i++){
      li.add(i) ;
    }
    long startTime = System.currentTimeMillis() ;
    for(int i=0;i<1000000;i++){
      li.get(i) ;   //print : 15
    }
    long endTime = System.currentTimeMillis() ;
    System.out.println(endTime-startTime) ;
  }
}

remove方法对LinkedList类的使用

a.利用iterator类

import java.util.* ;
public class ListDemo01{
  public static void main(String args[]){
    List<Integer> li = new LinkedList<Integer>() ;
    for(int i=0;i<1000000;i++){
      li.add(i) ;
    }
    long startTime = System.currentTimeMillis() ;
    Iterator<Integer> it = li.iterator() ;
    while(it.hasNext()){
      if(it.next()%2==0){
        it.remove() ;
      }
    }
    long endTime = System.currentTimeMillis() ;
    System.out.println(endTime-startTime) ;
  }
}

b.不利用iterator的话则则需要调用get方法。则效率很低

import java.util.* ;
public class ListDemo01{
  public static void main(String args[]){
    List<Integer> li = new LinkedList<Integer>() ;
    for(int i=0;i<1000000;i++){
      li.add(i) ;
    }
    long startTime = System.currentTimeMillis() ;
    for(int i=0;i<10000;i++){
      if(li.get(i)%2==0){
        li.remove(i) ;
      }
    }
    long endTime = System.currentTimeMillis() ;
    System.out.println(endTime-startTime) ;
  }
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ArrayList的自动扩充机制实例解析

    用一道选择题作为本文的开始吧! ArrayList list = new ArrayList(20);中的list扩充几次 A.0 B.1 C.2 D.3 答案:A 1.ArrayList的默认初始容量为10,当然也可以自定义指定初始容量,随着动态的向其中添加元素,其容量可能会动态的增加,那么扩容的公式为: 新容量 = 旧容量/2 + 旧容量 比如:初始容量为4,其容量的每次扩充后的新容量为:4->6->9->13->19->- 即每次扩充至原有基础的1.5倍 ArrayLi

  • Java中Arraylist动态扩容方法详解

    前言 本文主要给大家介绍了关于Java中Arraylist动态扩容的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. ArrayList 概述 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长.ArrayList不是线程安全的,只能用在单线程环境下.实现了Serializable接口,因此它支持序列化,能够通过序列化传输:实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问:实现了Cloneable接口,能被克隆.

  • Java中ArrayList的removeAll方法详解

    本文介绍的是关于Java中ArrayList的removeAll方法的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 在开发过程中,遇到一个情况,就是从所有骑手Id中过滤没有标签的骑手Id(直接查询没有标签的骑手不容易实现), List<Integer> allRiderIdList = new ArrayList(); // 所有的骑手,大致有23W数据 List<Integer> hasAnyTagRiderId = new ArrayList(); // 有标签

  • Java中ArrayList和LinkedList之间的区别_动力节点Java学院整理

    一.ArrayList ArrayList是一个可以处理变长数组的类型,这里不局限于"数"组,ArrayList是一个泛型类,可以存放任意类型的对象.顾名思义,ArrayList是一个数组列表,因此其内部是使用一个数组来存放对象的,因为Object是一切类型的父类,因而ArrayList内部是有一个Object类型的数组类存放对象.ArrayList类常用的方法有add().clear().get().indexOf().remove().sort().toArray().toStri

  • Java中struts2和spring MVC的区别_动力节点Java学院整理

    1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上SpringMVC就容易实现restful url,而struts2的架构实现起来要费劲,因为Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了. 2.SpringMVC的方法之间基本上独立的,独享request respons

  • Java中List Set和Map之间的区别_动力节点Java学院整理

    Java集合的主要分为三种类型: • Set(集) • List(列表) • Map(映射) 要深入理解集合首先要了解下我们熟悉的数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),而JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型. 世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合 有人想有可以自动扩展的数组,所以有了List 有的

  • Java中List  Set和Map之间的区别_动力节点Java学院整理

    Java集合的主要分为三种类型: • Set(集) • List(列表) • Map(映射) 要深入理解集合首先要了解下我们熟悉的数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),而JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型. 世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合 有人想有可以自动扩展的数组,所以有了List 有的

  • Java Thread中start()和run()的区别_动力节点Java学院整理

    start() 和 run()的区别说明 start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法.start()不能被重复调用. run()   : run()就和普通的成员方法一样,可以被重复调用.单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程! 下面以代码来进行说明. class MyThread extends Thread{ public void run(){ ... } }; MyThread mythread = new MyThr

  • Java中HashTable和HashMap的区别_动力节点Java学院整理

    HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的区别.主要的区别有:线程安全性,同步(synchronization),以及速度. HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap allows one null key and any number of null values.,而Hashtable则不行).这就是说,HashMap中如果在表中没有发现搜索键,或者如

  • Java中HashSet和HashMap的区别_动力节点Java学院整理

    什么是HashSet? HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象.如果我们没有重写这两个方法,将会使用这个方法的默认实现.. public boolean add(Object o)方法用来在Set中添加元素,当元素值重复时则会立即返回false,如果成功添加的话会返回true. 什

  • Java中抽象类和接口的区别_动力节点Java学院整理

    接口 1 因为java不支持多重继承,所以有了接口,一个类只能继承一个父类,但可以实现多个接口,接口本身也可以继承多个接口. 2 接口里面的成员变量默认都是public static final类型的.必须被显示的初始化. 3 接口里面的方法默认都是public abstract类型的.隐式声明. 4 接口没有构造方法,不能被实例化. 5 接口不能实现另一个接口,但可以继承多个接口. 6 类如果实现了一个接口,那么必须实现接口里面的所有抽象方法,否则类要被定义为抽象类. 抽象类 1 如果将一个类

  • Java中final,finally,finalize三个关键字的区别_动力节点Java学院整理

    final 当这个关键字修饰一个类时,意味着他不能派生出新的子类,也就是说不能被继承,因此一个类不能被同时声明为abstract和final.当final修饰变量或者方法时,可以保证他们在使用中不会被改变.被声明为final的变量必须在初始化时给定初值,以后在使用时只能被引用而不能被修改.同样,当final修饰一个方法时,这个方法不能被重载. finally 异常处理时提供finally来执行任何清楚操作.如果抛出一个异常,那么相匹配的catch子句就会被执行,然后控制就会转入finally块.

  • ArrayList详解和使用示例_动力节点Java学院整理

    第1部分 ArrayList介绍 ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口. ArrayList 继承了AbstractList,实现了List.它是一个数组队列,提供了相关的添加.删除.修改.遍历等功能. ArrayList 实现了RandmoAccess接口,即提

随机推荐