容器

  1. ArrayList
    0. 通过数组实现
    1. add,会进行扩容(当前数组大小 + (当前数组大小 / 2))
    2. remove,删除对应的下标,并通过System.arraycopy进行数组平移
    3. 不能使用for循环进行数组的删除,因为删除数组会平移,应该使用迭代器
    4. 多线程并发不能使用ArrayList,要使用CopyOnWriteArrayList
    5. 添加多,查找少应该使用LinkedList,避免频繁copy

  2. LinkedList
    0. 通过双向链表实现
    1. add直接在末尾添加一个Node
    2. remove,通过遍历记数找到对应的下标。index < (size >> 1)如果是前半段则顺序查找,如果是后半段则倒序查找
    3. 修改多,应该用LinkedList。查询多则使用ArrayList

  3. CopyOnWriteArrayList
    1. 底层原理与ArrayList相似
    2. 线程安全
    3. 每次数组操作都是通过拷贝新数组进行操作,然后再赋值回去
    4. add,通过ReentrantLock + 数组拷贝 + volatile实现线程安全。通过ReentrantLock加锁,volatile实现内存共享,数组拷贝触发内存地址变更,同步其他线程
    5. 尽量使用addAll和removeAll,来进行批量操作,因为每次add或remove都会进行一次数组拷贝。

  4. hashMap
    0. 数组 + 链表 + 红黑树实现
    1. 当链表长度大于8链表转为红黑树,当红黑树大小小于等于6时,变回链表。(红黑树的出现是为了解决链表过长的问题)
    2. put的实现过程:1. 对key计算Hash值(计算公式:hash = (h = key.hashCode()) ^ (h >>> 16)) 2. 通过计算((n - 1) & hash)获得数组的下标,如果对应的下标中没有值,则直接进行赋值。如果有值,意味着发生了hash冲突,需要解决冲突。 3. 出现冲突时首先判断key是否相等,内存地址是否相等。如果都相等,那就直接覆盖。 4. 如果key不相等,则先判断当前的node,如果是红黑树,则根据红黑树的规则直接插入。如果是链表,则直接插入链表末尾。如果链表长度大于等于8且数组长度大于64,则扩展为红黑树。
    3. 为什么链表长度是8?
    因为当链表长度为8时,链表的冲突概率已经很小了。为了处理特殊情况(大于等于8)就转为红黑树。虽然红黑树的访问复杂度是O(LogN),链表的是O(n),红黑树比链表访问要快,但是红黑树的内存占用是链表的2倍。
    4. 扩容算法(参考
    jdk1.7:在插入元素时,判断如果当前元素(键值对)个数超过阈值,并且出现了hash冲突,此时会进行扩容,将数组变为原来的两倍,并且所有元素重新计算hash,放到新的数组中。因为1.7中元素的链表插入是采用的头插法,所以多线程下会出现死循环的问题。
    jdk1.8:扩容是发生在插入元素之后。如果插入的链表后,链表个数是7个,那么就会进行扩容,如果数组长度超过64,则当前链表改为红黑树,如果没有超过64,则数组的大小变为原来的2倍。如果链表个数没有达到7个,则判断hashMap的元素个数是否超过阈值(size > 0.75 * 16),如果超过了,同样进行扩容(之后扩大数组的容量,不会转换红黑树)。
    5. 调用 new HashMap(1000) 构造方法,内部还会扩容吗?
    会的,因为HashMap的构造参数中还有一个加载因子(0.75),所以实际上容量不到1000,后续还需要扩容。加载因子的作用是判断HashMap内部是否需要扩容。即当内部容量达到1000 * 0.75 = 750之后,就会扩容,而不是达到1000才扩容。扩容之后,空间变大了,hash冲突降低了。

  5. ArrayMap
    0. 由两个数组组成的Map
    1. 数组1存放hash值,数组2存放key+value
    2. get,通过计算hash找到对应的下标,再通过二分查找,找到hash对应的key/value
    3. put,通过计算hash找到数组2中的下标,如果对应下标没有值,直接插入。如果有值,则插入到后面,后面的数组统一后移
    4. 缓存机制:缓存数组长度为4或者8的数组,每个上限10个。目的:为了减少频繁创建和销毁数组对象。

  6. ConcurrentHashMap
    0. 通过volatile修饰Map,保证其在内存中的可见性,确保线程同步
    1. 在putValue时,通过for循环和CAS自旋确保不会出现同步问题
    2. 在扩容时,会通过状态确保扩容过程
    3. 在操作节点时,通过synchronized锁住节点

  7. LinkedBlockingQueue和ArrayBlockingQueue
    在队列存放满后,存数据的线程会进入阻塞,等待空间。
    在队列为空时,取数据的线程会进入阻塞,等待新的数据到来。
    通过AQS的await进行阻塞,通过signal进行唤醒

    名字 底层实现 容量大小
    LinkedBlockingQueue 使用链表实现 Int.MAX_VALUE
    ArrayBlockingQueue 使用数组实现 需要初始化时指定容量
  8. LRU数据结构实现(https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247490403&idx=1&sn=dd361a87d74eec4ca9ef97efe016c906
    双向链表 + HashMap

参考资料:
面试官: 我必问的容器知识点! - 掘金 (juejin.cn)
Carson带你学Java:手把手带你源码分析 HashMap 1.7
重读源码之 SparseArray 和 ArrayMap

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

推荐阅读更多精彩内容