容器

一.容器

二.Map

 

 Map接口常见的实现类有HashMap、LinkedHashMap、TreeMap和ConcurrentHashMap

1.底层实现

HashMap                 |      数组+链表/红黑树  |

LinkedHashMap           |      数组+链表+双向链表|

TreeMap                 |      红黑树           |

ConcurrentHashMap       |      数组+链表/红黑树  |

2.HashMap

①数组的大小大于64且大于8就链表就转变为红黑树

②扩容为两倍(16)

③必须为2的幂,减少hash冲突

④加载因子是0.75

⑤1.7是头插法,1.8是尾插法

⑥有一个键可以为null

(1)大小是2次幂

HashMap的大小只能是2次幂的,假设你传一个10进去,实际上最终HashMap的大小是16,你传一个7进去,HashMap最终的大小是8,具体的实现在tableSizeFor可以看到。我们把元素放进HashMap的时候,需要算出这个元素所在的位置(hash)。在HashMap里用的是位运算来代替取模,能够更加高效地算出该元素所在的位置。为什么HashMap的大小只能是2次幂,因为只有大小为2次幂时,才能合理用位运算替代取模

(2)put

put的时候,首先对key做hash运算,计算出该key所在的index。如果没碰撞,直接放到数组中,如果碰撞了,需要判断目前数据结构是链表还是红黑树,根据不同的情况来进行插入。假设key是相同的,则替换到原来的值。最后判断哈希表是否满了(当前哈希表大小*负载因子),如果满了,则扩容。

 

(3)get

get的时候,还是对key做hash运算,计算出该key所在的index,然后判断是否有hash冲突,假设没有直接返回,假设有则判断当前数据结构是链表还是红黑树,分别从不同的数据结构中取出.

①判断首节点是否为想要get的Node
②如果首节点不是则判断是不是红黑树,如果是则以红黑树的方式遍历查找
③如果首节点是链表类型,则以链表的方式遍历查找

(4)HashMap和HashTable

HashMap HashTable
线程不安全 线程安全
效率高 效率低
可以有一个key为null 不允许存在null的key
扩容为一倍 扩容为一倍+1
默认容量为16 默认为11

(5)HashTable和ConcurrentHashMap的区别

ConcurrentHashMap的put方法加锁优化了,锁的精度提高了,速度也就提高了。

 https://www.php.cn/java/base/469764.html

3.LinkedHashMap

 

 

 

 HashMap是无序的,当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了。

其实在日常开发中LinkedHashMap用得不多。我在实习的时候,就用到了一处,导出Excel表时Mybatis查询返回类型就是LinkedHashMap,因为它能让返回的数据严格有序。

4.TreeMap

  红黑树

①首节点一点是黑色

②叶子节点也是黑色

③红色节点不可相连

④每条路径上的黑色节点数量一点要相等

5.ConcurrentHashMap

线程安全,跟HashMap差不多,就是在高并发的时候使用

三.List

ArrayList LinkedList
数组 链表
默认为0,add时才会初始化大小为10  
动态扩容,1.5倍  

1.ArrayList

是由底层的数据结构来决定的,在日常开发中,遍历的需求比增删要多,即便是增删也是往往在List的尾部添加就OK了。像在尾部添加元素,ArrayList的时间复杂度也就O(1)。ArrayList的增删底层调用的copyOf()被优化过,现代CPU对内存可以块操作,ArrayList的增删一点儿也不会比LinkedList慢

2.LinkedList

队列是用双向链表实现的

Queue<> queue = new LinkedList<>();

既然说到队列就提一嘴栈,栈底层使用Vector实现的,这是历史遗留问题,一开始java写的Vector不太行。

因为Vector是当初JAVA曾经写得不太行的类,所以Stack也不太行。
Vector不行是因为效率不太行,很多方法都用了synchronized修饰,
虽然线程安全,但是像ArrayDeque,LinkedList这些线程不安全的,
在需要安全的时候也可以用Collections.synchronizedCollection()
转化成线程安全的,所以Vector就没什么用处了

四.队列

在实现普通队列时,如何选择用 LinkedList 还是 ArrayDeque 呢?

总结来说就是推荐使用 ArrayDeque,因为效率高,而 LinkedList 还会有其他的额外开销

什么情况下你要选择用 LinkedList 呢?
答:如果版本是Java 6 以前。因为 ArrayDeque 在 Java 6 之后才有的。。
为了版本兼容的问题,实际工作中我们不得不做一些妥协。。

ArrayList和LinkedList的区别

  1. ArrayDeque 是一个可扩容的数组,LinkedList 是链表结构;
  2. ArrayDeque 里不可以存 null 值,但是 LinkedList 可以;
  3. ArrayDeque 在操作头尾端的增删操作时更高效,但是 LinkedList 只有在当要移除中间某个元素且已经找到了这个元素后的移除才是 O(1) 的;
  4. ArrayDeque 在内存使用方面更高效。

所以,只要不是必须要存 null 值,就选择 ArrayDeque 吧!

四.Set

 这个好像没什么好说的 0.0

 

posted @ 2020-10-27 19:04  拿着放大镜看世界  阅读(116)  评论(0编辑  收藏  举报