Java中常见数据结构(一)——ArrayList

Java中最常见的数据结构莫过于ArrayList与HashMap了
首先看看ArrayList类:
对于数据我们做的最多的 无非为 增删查 三项了,那么我们首先看看ArrayList增删查方法。
增 add方法:

add方法

add(E e)方法在末尾加入一个元素e
add(int index,E e)方法在指定位置加入一个元素。
删 remove方法:
remove方法

remove(int index) 指定位置的删除
remove(E e)指定元素的删除
查 get方法
get方法

get(int index)查找指定位置的元素

ArrayList 从名字我们能看出 底层的基本数据结构是由数组实现的,而数组的特性是随机查找的性能好,对于增加和删除操作效率较低,所以ArrayList 似乎是更适合用于数据查找的一种结构;为了应对改善这种性能缺陷我们有了另一个类 LinkedList
依然来看 增删查 三种方法

add(E e)

add(int index,E e)

remove(int index)

remove(Object o)

get(int index)

看方法似乎是一样的,那么ArrayList与LinkedList实现这些方法的区别在哪呢?
他们的区别也就是性能差异的地方了 首先看 get方法
get方法对比

左边为ArrayList的实现,右边为LinkedList的实现
可以看到 ArrayList的指定位置查找直接用数组的随机查找能力返回了结果,而LinkedList 进入了node(index)来查找结果
node(index)

node(index)中对链表进行了一次遍历,来查找目标位置的元素,当next的次数到达index 指定的位置时返回结果
时间复杂度数组的随机查找为 O(1) 而链表实现的时间复杂度为遍历的O(n)
在看添加方法
add(index,e)对比

add(e)对比

可以看到 每次add操作 ArrayList 都会对当前elementData数组的长度进行操作
而LinkedList则只对当前节点的前驱和后继进行了处理

我们知道数组一旦分配了空间长度就不能变了,但是ArrayList创建的时候我们并不知道需要的长度是多少,而底层又是不能改变长度数组结构,这里是怎么处理的呢?
数据长度的变化由add/remove 引起所以我们由add方法入手

add(index,e)

可以看见在加入新元素时 首先进行了一次ensureCapacityInternal(size+1)操作
直觉这里是对底层数组的扩容操作 进去看一下


ensureCapacityInternal中
首先判断了 当前数组是否是默认空数组,如果是比较新的容量与默认容量的大小来决定目标容量minCapacity。
接着进入ensureExplicitCapacity
判断了一下 目标容量minCapacity是否比当前已有容量大,如果需要扩容执行grow方法
进入grow方法中
旧容量oldCapacity 为现有元素的长度
新容量newCapacity = oldCapacity+(oldCapacity>>1);
即1.5倍原有容量
最终使用Arrays.copyOf(sourceArray,capacity);创建了新的数组
Arrays.copy

在创建新的数组后,使用System.arraycopy方法将原数组的数据复制到新的数组当中,一路返回到add(index,e)中
add(index,e)

此时完成了对数组的扩容,现在可以把新元素加入到数组中了,然后对记录元素数量的size 进行+1操作,完成添加流程

再看remove方法


remove(index)

可以看到,remove方法中并没有对已有数组的容量进行操作...
难道 我扩容到一个巨大的数组后再删除 ,这些空间就不会释放了吗?
绝望之时我看到了这个方法。


trimToSize()

看到 这里创建了一个与真实元素数量相同的数组来代替原有数据数组,去除了申请的那些预留空间 debug一下看看情况
befor

trimToSize之前 elementData.length=15


after

trimToSize之后 elementData.length=1;

最后我们看一下线程安全的ArrayList
首先是 Vector类 几乎不会使用

Vector的add

对方法进行加锁处理也就是对当前对象加了锁,该对象的其他方法也会受到限制。
CopyOnWriteArrayList
lock

add方法

可以看到我们锁住的对象是一个空的object
这个要比vector好,当前list对象的其他方法不会受到限制

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容