Java常用容器知识速成

image

一.继承关系

1.1 基于Collection

Iterable接口: 迭代器(负责迭代元素,用于遍历元素)
Collection接口: 集合(常用的方法有添加,全部添加,删除,清空集合,是否存在,集合个数等)
List接口: 列表 (list提供比数组更丰富的API,有序,可重复,)
Queue接口: 队列(遵循先进先出原则,第一个进队列的元素,必定第一个出队列)
Set接口: Set集合(不允许出现重复元素,并且无序的集合)

容器继承关系图

1.2 不属于Collection

Map接口: 散列表(使用K-V(键值对)存储的一种数据结构,Key 是无序的、不可重复的,value 是无序的、可重复的)不属于Collection接口

Java Map Hierarchy

二.List

2.1 ArrayList

底层实现: Objcet[] (动态数组)

扩容方式: 当原本ArrayList的底层的数组容量不足以存放新插入的元素或一组元素时,会触发扩容机制,调用的本地C方法。

线程安全性: 不安全
补充:如果要安全的调用ArrayList,使用Collections.synchronizedList()方法。其他API与原先无异

List<Map<String,Object>> data=Collections.synchronizedList(new ArrayList<Map<String,Object>>());

使用场景:
适合于进行大量的随机访问的情况下使用(说人话就是可以直接根据下标取值),时间复杂度O(1)

插入与删除: 默认追加到尾部,时间复杂度O(1)。追加或删除指定位置元素,时间复杂度 O(n-i)

补充:clear()方法可以清空当前List且不改动已分配的空间

2.2 LinkedList

底层实现: 双向链表

扩容方式: 正常链表的新增节点

线程安全性: 不安全
补充:如果要安全的调用,同上。其他API与原先无异

List<Map<String,Object>> data=Collections.synchronizedList(new LinkedList<Map<String,Object>>());

使用场景:
适合频繁的插入或者删除操作,较少的随机访问(说人话就是可以直接根据下标取值),获取元素的时间复杂度O(n)。

插入与删除: 默认追加到尾部,时间复杂度约等于O(1)(为啥不等于一,因为还要创建节点然后追加,而ArrayList直接分配好空间直接赋值就行)。追加或删除指定位置元素,时间复杂度近似 O(n)

内存空间占用:
ArrayList 的空间浪费体现在 list 列表的结尾会预留一定的容量空间
LinkedList 的空间花费主要体现在每一个元素都(存放直接后继和直接前驱以及数据) 需要消耗比 ArrayList 更多的空间。

2.3 CopyOnWriteArrayList(不常用)

底层实现: Objcet[] (动态数组)

线程安全性: 安全
补充:如何保证安全性,
读:未加锁。
写:添加或修改时元素时 使用lock()进行加锁并复制 一份 副本,然后添加或修改,然后使用新副本。

使用场景:
适合于进行大量的随机访问的情况下使用(说人话就是可以直接根据下标取值)以及读多写少的情况,不需要强一致性(不能保证即时一致性),时间复杂度O(1)。

内存空间占用:
每一次写都需要复制一份副本。严重浪费内存。

2.4 Vector(历史遗留,古早时代的类)

底层实现: Objcet[] (动态数组)

线程安全性: 安全
补充:如何保证安全性,方法全部加了 synchronized 关键字(恶臭的历史残留。进了用这玩意的公司赶紧跑路吧,代码一定是屎山)

三.Set

3.1 HashSet

底层实现: HashMap(使用了Key部分)

线程安全性: 不安全

使用场景: 无序,数据去重
允许插入Null值

3.2 TreeSet

底层实现: TreeMap,红黑树(自平衡二叉查找树)

线程安全性: 不安全

使用场景: 有序(自然排序,key的开头第一个字符的顺序a-z,或者数字的大小0-9)或自定义排序,数据去重
允许插入Null值

注意:要安全调用非线程安全的Set。调用Collections.synchronizedSet()

四.Map

4.1 HashMap

底层实现: 哈希表(又称散列表,使用杂凑算法),当链表(存放相同Hash值的Value)长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64(存Key),那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。

线程安全性: 不安全

扩容机制:
源码规定了默认扩容加载因子为0.75

面试官:为什么是0.75?
如果是0.5,就是说哈希表填到一半就开始扩容了,这样会导致扩容频繁,并且空间利用率比较低。 如果是1,就是说哈希表完全填满才开始扩容,这样虽然空间利用提高了,但是哈希冲突机会却大了。
负载因子0.75就是冲突的机会 与空间利用率权衡的最后体现,也是实验的经验值。

static final float DEFAULT_LOAD_FACTOR = 0.75f;

使用场景: 需要根据键的hashCode值进行存储数据。无序,获取元素的时间复杂度限制为O(1)的时候。
Key与Value可为null

内存空间占用:

① 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。
面试官为什么是16?
如果太小,4或者8,扩容比较频繁;如果太大,32或者64甚至太大,又占用内存空间。
位运算更快,不需十进制和二进制相互转换。

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

② 创建时如果给定了容量初始值 HashMap 会将其扩充为 2 的幂次方大小,也就是说 HashMap 总是使用 2 的幂作为哈希表的大小。

简单的杂凑算法演示: 设对7求膜,
新增key:6 ,value:"随便"

6%7=6

数组 数组0 数组1 数组2 数组3 数组4 数组5 数组6 数组7 数组8 数组9
Key null null null null null null 6 null null null
Value null null null null null null "随便" null null null

新增key:7 ,value:"第二次"

7%7=0

数组 数组0 数组1 数组2 数组3 数组4 数组5 数组6 数组7 数组8 数组9
Key 7 null null null null null 6 null null null
Value "第二次" null null null null null "随便" null null null

解决Hash冲突: 拉链法(以链表的形式存放相同Hash值的Value),上文的红黑树也可。但是拉链法较简单。

4.2 TreeMap

底层实现: 红黑树

线程安全性: 不安全

使用场景: 有序(自然排序,key的开头第一个字符的顺序a-z,或者数字的大小0-9)或自定义排序。
Key与Value可为null

注意:要安全调用非线程安全的Map。调用Collections.synchronizedMap()

4.3 ConcurrentHashMap(建议使用)

底层实现: 数组+链表/红黑二叉树(JDK1.8)在链表长度超过一定阈值(8)时将链表(寻址时间复杂度为 O(N))转换为红黑树(寻址时间复杂度为 O(log(N)))

线程安全性: 安全

保证线程安全的方法:用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。

java8concurrenthashmap.png

效率问题:
synchronized 只锁定当前链表或红黑二叉树的首节点,这样只要 hash 不冲突,就不会产生并发,效率又提升 N 倍。

4.4 Hashtabel(古早的线程安全类)

如何保证安全性,方法全部加了 synchronized 关键字(恶臭的历史残留。进了用这玩意的公司赶紧跑路吧,代码一定是屎山)

资料参考

JavaGuide:https://snailclimb.gitee.io/javaguide
CSDN:https://blog.csdn.net

联系方式

公众号:青山有录
Github:https://github.com/z875479694h
博客:https://www.hcworld.xyz

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

推荐阅读更多精彩内容