这里主要包含ArrayList和LinkedList.

关于Java中的集合内容, 感觉都已经被写烂了, 我这里主要是做个复习, 再从扒下源代码, 尽量用最直白的语言把里面的核心内容记录下来。仅此而已。

首先放一个Collection下的UML图:(此图是idea通过diagram功能生成的, 基于JDK7)

一、ArrayList

1, for-each原理:

0、 在编译的时候编译器会自动将对for这个关键字的使用转化为对目标的迭代器的使用,这就是foreach循环的原理

1、ArrayList之所以能使用foreach循环遍历,是因为ArrayList所有的List都是Collection的子接口,而Collection是Iterable的子接口,ArrayList的父类AbstractList正确地实现了Iterable接口的iterator方法。之前我自己写的ArrayList用foreach循环直接报空指针异常是因为我自己写的ArrayList并没有实现Iterable接口

2、任何一个集合,无论是JDK提供的还是自己写的,只要想使用foreach循环遍历,就必须正确地实现Iterable接口。

2, 集合中的 fail-fast iterator:

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

当使用foreach遍历一个list元素时, 因为foreach底层实现是使用iteator中的hasNext, next等, 源码中next执行时会checkForComdification:

3, ArrayList初始值大小是10, 每次扩容是增加2倍。优缺点是:

//默认的构造函数, 当然还有构造函数是可以指定大小的
public ArrayList() {
this(10);
} //jdk7中的扩容代码, 我看了jdk6中是扩容1.5倍的, 这里有点差别
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:
elementData = Arrays.copyOf(elementData, newCapacity);
}

ArrayList的优点:

1、ArrayList底层以数组实现,是一种随机访问模式,再加上它实现了RandomAccess接口,因此查找也就是get的时候非常快

2、ArrayList在顺序添加一个元素的时候非常方便,只是往数组里面添加了一个元素而已

ArrayList的缺点:

1、删除元素的时候,涉及到一次元素复制,如果要复制的元素很多,那么就会比较耗费性能

2、插入元素的时候,涉及到一次元素复制,如果要复制的元素很多,那么就会比较耗费性能

因此,ArrayList比较适合顺序添加、随机访问的场景。

4,细节: 为什么ArrayList的elementData是用transient修饰的?

ArrayList实现了Serializable接口,这意味着ArrayList是可以被序列化的,用transient修饰elementData意味着我不希望elementData数组被序列化。这是为什么?因为序列化ArrayList的时候,ArrayList里面的elementData未必是满的,比方说elementData有10的大小,但是我只用了其中的3个,那么是否有必要序列化整个elementData呢?显然没有这个必要,因此ArrayList中重写了writeObject方法:

private transient Object[] elementData;
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject(); // Write out array length
s.writeInt(elementData.length); // Write out all elements in the proper order.
for (int i=0; i<size; i++)
s.writeObject(elementData[i]); if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
} }

每次序列化的时候调用这个方法,先调用defaultWriteObject()方法序列化ArrayList中的非transient元素,elementData不去序列化它,然后遍历elementData,只序列化那些有的元素,这样:

1、加快了序列化的速度

2、减小了序列化之后的文件大小

Java中常见数据结构List之ArrayList的更多相关文章

  1. Java中常见数据结构:list与map -底层如何实现

    1:集合 2 Collection(单列集合) 3 List(有序,可重复) 4 ArrayList 5 底层数据结构是数组,查询快,增删慢 6 线程不安全,效率高 7 Vector 8 底层数据结构 ...

  2. Java中常见数据结构List之LinkedList

    二,LinkedList 1, linkedList底层数据结构 linkedList底层是一个双向链表 2,LinkedList和ArrayList的对比 1.顺序插入速度ArrayList会比较快 ...

  3. Java中常见数据结构:list与map

    1:集合 Collection(单列集合) List(有序,可重复) ArrayList 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector 底层数据结构是数组,查询快,增删慢 线程 ...

  4. Java中常见数据结构Map之LinkedHashMap

    前面已经说完了HashMap, 接着来说下LinkedHashMap. 看到Linked就知道它是有序的Map,即插入顺序和取出顺序是一致的, 究竟是怎样做到的呢? 下面就一窥源码吧. 1, Link ...

  5. Java中常见数据结构Map之HashMap

    之前很早就在博客中写过HashMap的一些东西: 彻底搞懂HashMap,HashTableConcurrentHashMap关联: http://www.cnblogs.com/wang-meng/ ...

  6. Java中常见数据结构

    1:集合 Collection(单列集合) List(有序,可重复) ArrayList 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector 底层数据结构是数组,查询快,增删慢 线程 ...

  7. Java中常见数据结构Set之HashSet

    今天来说说Java集合中的Set系列之HashSet.   Set我们众所周知的就是虑重功能, 我们平时在项目开发中也常用到这个特性的.那么Set为何能够虑重呢? 接下来我们就看下源码吧.   Set ...

  8. Java基础-JAVA中常见的数据结构介绍

    Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...

  9. java中的数据结构(集合|容器)

    对java中的数据结构做一个小小的个人总结,虽然还没有到研究透彻jdk源码的地步.首先.java中为何需要集合的出现?什么需求导致.我想对于面向对象来说,对象适用于描述任何事物,所以为了方便对于对象的 ...

随机推荐

  1. MySQL--当mysqldump --single-transaction遇到alter table

    部分生产环境采用mysqldump --single-transaction的方式在夜间进行数据库备份,而同事恰好在备份期间执行了alter table操作,操作部分成功部分失败,为啥呢? 在mysq ...

  2. 使用matplotlib快速绘图

    matplotlib的pyplot子库提供了和matlab类似的绘图API,方便用户快速绘制2D图表.让我们先来看一个简单的例子: # -*- coding: utf-8 -*- import num ...

  3. Ant部署(linux)

    1.下载 mkdir /opt/ant cd /opt/ant wget http://mirror.bit.edu.cn/apache//ant/binaries/apache-ant-1.9.4- ...

  4. MS SQL Server Management Studio中提示不允许保长度出现不允许保存更改。您所做的更改要求删除并重新创建以下表

    在SQL Server Management Studio中直接修改正在连接的表结构会出现改不了的情况,如下图 解决方法:工具-选项-设计器--阻止保存要求重新创建表的更改,去掉对勾--确定即可

  5. python基础(3):输入输出与运算符

    今天总结一下最基础的输入输出和运算符 输入: python3里都是input("") input() name = input()    #输入的值会直接赋值给name name ...

  6. js 数组里求最大值和最小值

    // 数组里相邻两个数做比较 取满足条件的那个(以此类推) var arr = [1,3,4,5,6,7]; function Max(array){ var max = array[0]; for( ...

  7. 常用的DNS

    中国互联网络中心(推荐,安全又快速):1.2.4.8.210.2.4.8.101.226.4.6(电信及移动).123.125.81.6(联通)阿里DNS:223.5.5.5.223.6.6.6goo ...

  8. nopCommerce 3.9 大波浪系列 之 路由注册

    在Global.asax,Application_Start()方法中会进行路由注册,代码如下. public static void RegisterRoutes(RouteCollection r ...

  9. Ajax获取服务器信息

    xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && ...

  10. iOS开发实战-时光记账Demo 本地数据库版

    现在记账APP也是用途比较广泛 自己写了个简单的demo 欢迎指正 效果 分析 1.思维推导 首先简单的做了下思维推导 2.文件结构 大致框架想好后就可以着手开始准备了 数据库管理:coreData ...