集合类

List

ArrayList底层是数组,LinkedList底层是链表。数组遍历速度快,LinkedList增删元素快。

在工作中一般就用ArrayList,而不用LinkedList,原因也很简单:

  • 在工作中,遍历的需求比增删多,即便是增加元素往往也只是从尾部插入元素,而ArrayList在尾部插入元素也是O(1)

  • ArrayList增删没有想象中慢,ArrayList的增删底层调用的copyOf()被优化过,加上现代CPU对内存可以块操作,普通大小的ArrayList增删比LinkedList更快。

List集合常用的子类有三个:

  • ArrayList,底层数据结构是数组。线程不安全

    • ArrayList是基于动态数组实现的,在增删时候,需要数组的拷贝复制

    • ArrayList的默认初始化容量是10,每次扩容时候增加原先容量的一半,也就是变为原来的1.5倍

    • 删除元素时不会减少容量,若希望减少容量则调用trimToSize()

    • 它不是线程安全的。它能存放null值。

  • LinkedList,底层数据结构是链表。线程不安全

    • 底层实现是双向链表[双向链表方便实现往前遍历]

  • Vector,底层数据结构是数组。线程安全,方法带有synchronized

    • 底层是数组,现在已少用,被ArrayList替代,原因有两个:

    • Vector所有方法都是同步,有性能损失

    • Vector初始length是10 超过length时 以100%比率增长,相比于ArrayList更多消耗内存

Set

Set常用子类:

  • HashSet集合,底层数据结构是哈希表(是一个元素为链表的数组)

  • TreeSet集合,底层数据结构是红黑树(是一个自平衡的二叉树),保证元素的排序方式

  • LinkedHashSet集合,底层数据结构由哈希表和链表组成。

Map

散列表

散列表为每个对象计算出一个整数,称为散列码根据这些计算出来的整数(散列码)保存在对应的位置上!在Java中,散列表用的是链表数组实现的,每个列表称之为桶

一个桶上可能会遇到被占用的情况(hashCode散列码相同,就存储在同一个位置上),这种情况是无法避免的,这种现象称之为:散列冲突

  • 此时需要用该对象与桶上的对象进行比较,看看该对象是否存在桶子上了~如果存在,就不添加了,如果不存在则添加到桶子上

  • 当然了,如果hashcode函数设计得足够好,桶的数目也足够,这种比较是很少的~

  • JDK1.8中,桶满时会从链表变成平衡二叉树

各种常见的树的用途:

img

红黑树

红黑树用的是是两种方式来实现节点交换操作:

  • 旋转:顺时针旋转和逆时针旋转

  • 反色:交换红黑的颜色

红黑树为了保持平衡,还有制定一些约束,遵守这些约束的才能叫做红黑树:

  1. 红黑树是二叉搜索树。

  2. 根节点是黑色

  3. 每个叶子节点都是黑色的空节点(NIL节点)

  4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点(每一条树链上的黑色节点数量(称之为“黑高”)必须相等)

HashMap和HashTable

从存储结构和实现来讲基本上都是相同的。它和HashMap的最大的不同是它是线程安全的,另外它不允许key和value为null。Hashtable是个过时的集合类,不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换

Queue队列

生产者和消费者模式,最简单的方式就是用阻塞队列去写

 

 

原文地址:https://www.cnblogs.com/yjh1995/p/13514610.html