ArrayList 与 LinkedList的区别
今天查看源码,分析一下两者的异同。外加阐述内部类。
内部类参考官方文档,地址如下:
https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
本文思路是从两者的构造函数着手,之后是add()分析。
1.构造函数
 public class Test {
 
       // 下面两行不多说,就是创建List,这时注意一点,在构造函数中,尽量指定集合的大小。你可能会问,不指定的话,不是会有默认的size吗?完全正确。
       // 但是当程序指定默认的size后,当集合变大需要扩容的时候,会阻碍一部分性能,所以如果能够预知list的size,尽量指定合理的大小。
     List<String> aList = new ArrayList<String>();
       // List<String> aList = new ArrayList<String>(16);
     List<String> bList = new LinkedList<String>();
       // List<String> bList = new LinkedList<String>(16);
 }
 /**
      * Constructs an empty list with the specified initial capacity.
      *
      * @param  initialCapacity  the initial capacity of the list
      * @throws IllegalArgumentException if the specified initial capacity
      *         is negative
      */
       // 带有size大小的初期化方法,没什么可说的。判断size大小
     public ArrayList(int initialCapacity) {
         if (initialCapacity > 0) {
             this.elementData = new Object[initialCapacity];
         } else if (initialCapacity == 0) {
             this.elementData = EMPTY_ELEMENTDATA;
         } else {
             throw new IllegalArgumentException("Illegal Capacity: "+
                                                initialCapacity);
         }
     }
     /**
      * Constructs an empty list with an initial capacity of ten.
      */
       // 默认构造器
     public ArrayList() {
         this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
     }
/**
* Constructs an empty list.
*/
public LinkedList() {
}
2. ArrayList的add()方法
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
// 扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
// 在最后位置赋值
elementData[size++] = e;
return true;
}
 private void ensureCapacityInternal(int minCapacity) {
         // 判断list是否为空,如果为空,则为list指定默认容量,DEFAULT_CAPACITY的值是10
         if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
             minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
         }
         // 进行扩容
         ensureExplicitCapacity(minCapacity);
     }
     private void ensureExplicitCapacity(int minCapacity) {
           // 这个变量记录list结构扩容的次数,更具体的用处是什么,稍后研究。如果有想法的朋友,一起探讨
         modCount++;
         // overflow-conscious code
         if (minCapacity - elementData.length > 0)
             grow(minCapacity);
     }
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
// 大家在这里可以按到ArrayList使用的是数组结构,当元素增加或减少时会将数组进行复制,因此查询速度快,增加或删除时,相对较慢。
16 elementData = Arrays.copyOf(elementData, newCapacity);
} private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
3. LinkedList的add()方法
     public boolean add(E e) {
         linkLast(e);
         return true;
     }
 /**
      * Links e as last element.
      */
     void linkLast(E e) {
         final Node<E> l = last;
           // 封装了数据e的新节点
         final Node<E> newNode = new Node<>(l, e, null);
         last = newNode;
           // 如果是null表明链表中数据为空,那么将新节点设置为首节点,如果不为空,则增加的最后一个节点。
           // 因此在查询的时候,需要从头一直查到最后一个,效率较慢,但是面对增加删除时,只需更该其中的关联的前后节点,不必进行数组的复制,因此性能得以提升。
         if (l == null)
             first = newNode;
         else
             l.next = newNode;
         size++;
         modCount++;
     }
我们在查看Node<E>这个类时,会发现它是个静态内部类。
 private static class Node<E> {
         E item;
         Node<E> next;
         Node<E> prev;
         Node(Node<E> prev, E element, Node<E> next) {
             this.item = element;
             this.next = next;
             this.prev = prev;
         }
     }
内部类有什么作用,以前为什么会有静态内部类和非静态内部类呢?
我呢就不做搬运工了,在此呢推荐个官方文章,https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
里面详细阐述了内部类的分类,使用的好处等。
ArrayList 与 LinkedList的区别的更多相关文章
- LintCode Reverse LinkedList (ArrayList 和 LinkedList 的区别)
		
1. ArrayList 和 LinkedList 的区别 http://pengcqu.iteye.com/blog/502676 2. How to reverse LinkedList http ...
 - 你真的说的清楚ArrayList和LinkedList的区别吗
		
参见java面试的程序员,十有八九会遇到ArrayList和LinkedList的区别?相信很多看到这个问题的人,都能回答个一二.但是,真正搞清楚的话,还得花费一番功夫. 下面我从4个方面来谈谈这个问 ...
 - java集合框架05——ArrayList和LinkedList的区别
		
前面已经学习完了List部分的源码,主要是ArrayList和LinkedList两部分内容,这一节主要总结下List部分的内容. List概括 先来回顾一下List在Collection中的的框架图 ...
 - Java中ArrayList与LinkedList的区别
		
Java中ArrayList与LinkedList的区别 一般大家都知道ArrayList和LinkedList的区别: 1. ArrayList的实现是基于数组,LinkedList的实现是基于双向 ...
 - Java进阶(十七)ArrayList与LinkedList的区别
		
ArrayList与LinkedList的区别 ArrayList ArrayList其实是包装了一个数组 Object[],当实例化一个ArrayList时,一个数组也被实例化,当向ArrayLis ...
 - 【转】ArrayList与LinkedList的区别和适用场景
		
ArrayList 优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的). 缺点:因为地址连续,当要插入和删除时,Arra ...
 - JAVA中ArrayList与LinkedList的区别以及对应List使用foreach与使用下标遍历的效率问题
		
近期在做一个对接京东的电商平台,所以对各个地方的效率考虑的比较多,今天深挖了一下ArrayList与LinkedList的区别以及对应List使用foreach与使用下标遍历的效率问题,首先说一下两种 ...
 - 理解ArrayList与LinkedList的区别
		
一.先来看看ArrayList与LinkedList 在JDK中所在的位置 从图中可以看出,ArrayList与LinkedList都是List接口的实现类,因此都实现了List的所有未实现的方法,只 ...
 - java集合框架之ArrayList与LinkedList的区别
		
参考http://how2j.cn/k/collection/collection-arraylist-vs-linkedlist/690.html#nowhere ArrayList和LinkedL ...
 - Java自学-集合框架 ArrayList和LinkedList的区别
		
ArrayList和LinkedList的区别 步骤 1 : ArrayList和LinkedList的区别 ArrayList ,插入,删除数据慢 LinkedList, 插入,删除数据快 Arra ...
 
随机推荐
- nginx:支持https
			
1.查看nginx模块 nginx -V 注意是大写的V,小写的v是查看版本号的命令. 如果看到with-ssl那就是有的 2.注册ssl证书并下载 免费的ssl证书有: Let's Encrypt ...
 - flask-security(一)快速入门
			
很多例程都是基于flask-sqlalchemy的. 但是我使用sqlalchemy,并没有使用sqlalchemy,看中的也就是flask的灵活性. 暂时写flask的程序,但是为了以后写别的程序方 ...
 - Linux输入子系统 : 按键驱动
			
一.Linux input system框架: 1.由输入子系统核心层(input.c),驱动层(gpio_keys.c)和事件处理层(Event Handler)三部份组: 2.主要的三个结构体:i ...
 - .NET界面控件DevExpress全新发布v18.2.6|附下载
			
DevExpress Universal Subscription(又名DevExpress宇宙版或DXperience Universal Suite)是全球使用广泛的.NET用户界面控件套包,De ...
 - C# 连接EXCEL 和 ACCESS
			
97-2003版本 EXCEL Provider=Microsoft.Jet.OLEDB.4.0;Data Source=文件位置;Extended Properties=Excel 8.0;HDR= ...
 - 什么是lambda函数,它有什么好处
			
编程中提到的lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是值匿名函数. python允许你定义一种单行的小函数.定义lambda函数的形式如下lambda参 ...
 - 图片宽度为2000px,使图片在电脑不同分辨率下都水平居中,不压缩。
			
<div style="postion:relative;width:100%;overflow:hidden;"> <img src="路径" ...
 - 渲染Web视图
			
Spring MVC定义了一个名为ViewResolver的接口 public interface ViewResolver{ View resolveViewName(String viewName ...
 - Http put与post区别
			
转载: 有的观点认为,应该用POST来创建一个资源,用PUT来更新一个资源:有的观点认为,应该用PUT来创建一个资源,用POST来更新一个资源:还有的观点认为可以用PUT和POST中任何一个来做创建或 ...
 - [LeetCode&Python] Problem 448. Find All Numbers Disappeared in an Array
			
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...