• 1. Java数据结构
    • 1.1 数组(Array)
    • 1.2 链表(Linked List)
    • 栈(Stack)
    • 1.3 队列(Queue)
    • 1.4 树(Tree)
    • 1.5 堆(Heap)
    • 1.6 图(Graph)
    • 1.7 哈希表(Hash)
  • 2. 集合类图
  • 3. List接口常用的实现类
    • 3.1 ArrayList
    • 3.2 LinkedList
    • 3.3 Vector
    • 3.4 CopyOnWriteArrayList
  • 4. Set接口常用的实现类
    • 4.1 HashSet
    • 4.2 TreeSet
  • 5. Map接口常用的实现类
    • 5.1 HashMap
      • 5.1.1 红黑树和链表转换
      • 5.1.2 HashMap 重要属性
      • 5.1.3 HashMap 插入流程
      • 5.1.4 HashMap 扩容流程
      • 5.1.5 e.hash & oldCap == 0
      • 5.1.6 JDK1.8 做了哪些优化
      • 5.1.6 为什么用String类型当HashMap的key
    • 5.2 HashTable
    • 5.3 SortedMap
    • 5.4 ConcurrentHashMap
    • 5.5 LinkedHashMap

1. Java数据结构

1.1 数组(Array)

 1. 需要连续的内存空间。2. 按照索引查询速度快。复杂度O(1)3. 随机添加删除元素慢。需要移动元素。4. 无法扩容。创建的时候就确定。5. 数组只能存储一种类型的数据。

1.2 链表(Linked List)

分为:单向链表和双向链表

 1. 一种递归的数据结构,分为数据部分和节点引用。2. 因为存储了节点的引用,故需要更多的存储空间。3. 无需连续的内存空间4. 不需要初始化容量且链表长度可扩展。5. 插入删除速度快,只需要更新引用,无需移动数据。6. 查询速度慢,需要遍历链表。复杂度O(n)。

栈(Stack)

1. 按照“后进先出”、“先进后出”的原则来存储数据。

1.3 队列(Queue)

1. 按照““先进先出”的原则来存储数据。

1.4 树(Tree)

1. 非线性结构,它是由 n(n>0)个有限节点组成的一个具有层次关系的集合。
2. 二叉树:每个节点最多包含两个子树。
3. 平衡二叉树:当且仅当任何节点的两棵子树的高度差不大于 1 的二叉树。
4. 红黑树:平衡二叉树的一种,通过颜色的约束来维持着二叉树的平衡。

1.5 堆(Heap)

1. 堆可以被看做是一棵树的数组对象。
2. 堆中某个节点的值总是不大于或不小于其父节点的值。
3. 堆总是一棵完全二叉树。
4. 将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

1.6 图(Graph)

1. 复杂的非线性结构,由顶点的又穷非空集合和顶点之间边的集合组成。
2. 通常表示为G(V,E),G表示图,V表示顶点集合,E表示边的集合。
3. 图的节点之间的关系是任意的。

1.7 哈希表(Hash)

1. 是一种可以通过关键码值(key-value)直接访问的数据结构。
2. 快速实现查找、插入和删除。

2. 集合类图

3. List接口常用的实现类

主要是为顺序存储诞生的,List接口是为了存储一组不唯一的(允许重复)有序的对象。

3.1 ArrayList

1. 底层采用了数组这种数据结构;
2. 非线程安全;
3. 集合类型是Object类型;
4. 初始容量是10,扩容到原容量的1.5倍;

扩容

  1. 数组的扩容是新建一个大容量(原始数组大小+扩充容量)的数组;
  2. 然后将原始数组数据拷贝到新数组(Arrays.copyOf浅复制);
  3. 然后将新数组作为扩容之后的数组。

序列化

  • ArrayList 底层是一个Object[]对象(elementData);
  • elementData 被 transient,表示不能被序列化;
  • 不直接序列化这个对象,是因为这个对象绝大多数情况下会有没有存储任何元素的容量空间。这样将会是一个很大的空间浪费。
  • 而ArrayList 的序列化是对ArrayList 里面每个元素进行序列化的反序列化的。

3.2 LinkedList

1. 底层采用了双向链表的数据结构;
2. 非线程安全;

3.3 Vector

1. 底层采用了数组这种数据结构;
2. 线程安全的,所有的方法都有synchronized关键字修饰,效率低;

3.4 CopyOnWriteArrayList

1. 底层数据结构和和ArrayList一样,不过是线程安全的;

4. Set接口常用的实现类

主要特性是不允许重复的集合。对象存储不可重复性,且无序。

4.1 HashSet

1. HashSet集合在new的时候,底层实际上new了一个HashMap集合。
2. 向HashSet集合中存储元素,实际上是存储到HashMap集合中的key位置;
3. HashMap集合是一个哈希表数据结构。

4.2 TreeSet

1. TreeSet集合实际是TreeMap,new TreeSet集合的时候,底层实际上new了一个TreeMap集合。
2. 向TreeSet集合中存储元素,实际上是存储到TreeMap集合中的key位置;
3. TreeSet集合采用了二叉树数据结构。

5. Map接口常用的实现类

主要特征是Key-value。Map会维护与Key对应的值。

5.1 HashMap

1. 底层是哈希表数据结构。
2. 非线程安全;
3. 初始化容量是16,扩容是之前的2倍;
4. key和Value都允许为null.


JDK1.8之前是 数组 + 链表,之后是数组 + 链表 + 红黑树 实现的。

5.1.1 红黑树和链表转换

链表转红黑树的条件

  • 链表长度超过8个;
  • 数据长度大于等于64;如果小于64则会进行扩容。

红黑树转链表的条件

  • 同一个索引位置的节点在移除后数量少于6个;
  • 该索引位置的节点为红黑树节点。

5.1.2 HashMap 重要属性

  • size:已经存储的节点个数;
  • threshold:扩容阈值,当HashMap的个数达到该值,触发扩容。初始化时的容量。
  • loadFactor:负载因子,扩容阈值 = 容量 * 负载因子。负载因子越大则散列表的装填程度越高,也就是能容纳更多的元素,元素多了,链表大了,所以此时索引效率就会降低。反之浪费空间,但索引效率会提高。

5.1.3 HashMap 插入流程


其中hash计算方式 = key.hashCode() ^ key >>> 16;
n 为数组长度。

5.1.4 HashMap 扩容流程

5.1.5 e.hash & oldCap == 0

扩容后,新表的n-1 只比老表的的 n-1 在高位多了一个1。
而这一位的值刚好等于 oldCap。
所以e.hash & oldCap == 0 则新索引位置等于原索引位置;e.hash & oldCap != 0 则新索引位置等于原索引位置 + oldCap 位置。

5.1.6 JDK1.8 做了哪些优化

  1. 数组 + 链表 改成 数组 + 链表 + 红黑树
  2. 头插法改成尾插法
  3. 扩容计算新节点的位置,h & (length -1) 改成 h & oldCap。
  4. hash计算优化,优化成 让高16位参与了运算。

5.1.6 为什么用String类型当HashMap的key

  • String 复写了hashCode方法,且是根据内容计算的hash值,而不是通过地址计算(Object的hashCode)。
  • String 是final 修饰的不可变的,故它的hashCode被缓存下来,不需要再次计算。
  • equals 方法 String自己就有实现。

5.2 HashTable

1. 底层是哈希表数据结构。
2. 线程安全,所有的方法都有synchronized关键字,效率比较低;
3. 初始化容量是11,扩容是:原容量*2+1;
4. key和Value都不允许为null.

5.3 SortedMap

1. 本身不可重复无序,但是此处有自动排序,按照大小进行排序。
2. 此接口的实现类有TreeMap(二叉树结构)。

5.4 ConcurrentHashMap

JDK1.7版本

1. 线程安全的,采用分段锁实现,默认16个Segment(也即并发数)。
2. 由一个个Segment组成,通过继承ReenTrantLock来进行加锁。

JDK1.8版本

1. ConcurrentHashMap结构基本上和Java8的HashMap一样。采用了数组+链表+红黑树的实现方式来设计,内部大量采用CAS操作,这里我简要介绍下CAS。
2. CAS是compare and swap的缩写,即我们所说的比较交换。cas是一种基于锁的操作,而且是乐观锁。
3. 其中value和next都用volatile修饰,保证并发的可见性。

版本差异对比

1. 数据结构:取消了Segment分段锁的数据结构,取而代之的是数组+链表+红黑树的结构。
2. 保证线程安全机制:JDK1.7采用segment的分段锁机制实现线程安全,其中segment继承自ReentrantLock。JDK1.8采用CAS+Synchronized保证线程安全。
3. 锁的粒度:原来是对需要进行数据操作的Segment加锁,现调整为对每个数组元素加锁(Node)。
4. 链表转化为红黑树:定位结点的hash算法简化会带来弊端,Hash冲突加剧,因此在链表节点数量大于8时,会将链表转化为红黑树进行存储。

5.5 LinkedHashMap

1. LinkedHashMap是继承于HashMap,是基于HashMap和双向链表来实现的。
2. LinkedHashMap有序,可分为插入顺序和访问顺序两种。如果是访问顺序,那put和get操作已存在的Entry时,都会把Entry移动到双向链表的表尾(其实是先删除再插入)。
3. LinkedHashMap存取数据,还是跟HashMap一样使用的Entry[]的方式,双向链表只是为了保证顺序。
4. LinkedHashMap是线程不安全的。

LinkedHashMap底层是数组+单向链表+双向链表。数组+链表就是HashMap的结构,双向链表维持插入顺序用。

Java 集合与数据结构相关推荐

  1. JAVA (集合和数据结构)

    Collection和Collections的区别: 1.java.util.Collection 是一个集合接口.它提供了对集合对象进行基本操作的通用接口方法.Collection接口在Java 类 ...

  2. Java集合框架——数据结构(二)

    数据结构 本节只讲述与集合相关的数据结构 1.常见的数据结构   数据存储的常用结构有:栈.队列.数组.链表和红黑树. 1.1.栈 结构 概述:     类似于:弹夹.桶 1.2.队列 结构 概述: ...

  3. Java集合常见数据结构-栈/队列/数组/链表/红黑树

    数组 链表 红黑树

  4. 再也不担心问到Java集合了,一文讲透Java中的数据结构

    Java数据结构实现详解 摘要 1 集合框架 1.1 顶层接口Iterable 1.2 Collection接口 2 List 2.1 List接口 2.2 List实现ArrayList 2.2.1 ...

  5. java集合结构----集合框架以及背后的数据结构

    2.选择排序和冒泡排序的原理和区别: 1.Collection常见的方法实例 1)咱们的JAVA集合框架是定义在java.util包底下的一组接口和实现类 2)实现Iterable接口的类可以通过fo ...

  6. java 头尾 队列_超详细的java集合讲解

    1 集合 1.1 为什么会出现集合框架 [1] 之前的数组作为容器时,不能自动拓容 [2] 数值在进行添加和删除操作时,需要开发者自己实现添加和删除. 1.2 Collection接口 1.2.1 C ...

  7. java集合总结_Java中集合总结

    Java数组的长度是固定的,为了使程序能够方便地存储和操作数目不固定的一组数据,JDK类库提供了Java集合,这些集合类都位于java.util包中,但是与数组不同的是,集合中不能存放基本类型数据,而 ...

  8. 考考基础部分,谈谈Java集合中HashSet的原理及常用方法

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:工匠初心 cnblogs.com/LiaHon/p/1125 ...

  9. Java集合框架综述,这篇让你吃透!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:平凡希 cnblogs.com/xiaoxi/p/60899 ...

最新文章

  1. arch更新失败的办法
  2. python学习第一章要点
  3. 腾讯面试:比特位计数
  4. 高性能必须有 多活塞卡钳
  5. 对mask进行rle编码然后进行解码-详细注释
  6. Codeforces Round #667 (Div. 3)
  7. PHP后台处理jQuery Ajax跨域请求问题 — xx was not called解决办法
  8. Bzoj 3289: Mato的文件管理 莫队,树状数组,逆序对,离散化,分块
  9. C语言 main 函数参数 main(int argc, char *argv[]) - C语言零基础入门教程
  10. JavaScript函数式编程入门经典
  11. 【分布式ID】键高并发 分布式 全局唯一 ID 雪花算法 snowflake
  12. Stm32串口通信基础实验
  13. lable 标签右对齐
  14. python搭建网盘网站_搭建nextcloud私有云存储网盘
  15. 虚拟现实跑步机Kat Walk自由来袭
  16. Senparc.Weixin.MP SDK 微信公众平台开发教程(十六):AccessToken自动管理机制
  17. python两点之间最短距离_最短路径(图中两点间最短路径)
  18. 小米商城秒杀脚本python
  19. 2022年,女生到底适合转行ui设计还是软件测试?
  20. 三节课-产品视角养成

热门文章

  1. 基于文字情感的民族音乐智能生成项目Bert+Magenta【音乐生成部分】(一)
  2. 剑指offer-8 跳台阶
  3. 如何添加表情包到博客文章
  4. 基于LLVM的编译原理简明教程: 写一个自己的编译器​
  5. Ping命令详解参数
  6. MediaSoup简介
  7. Python处理图片
  8. 解决360doc网站不登录就无法复制内容的方法
  9. 全民步入5G时代,现在我们都可以做什么?
  10. 学生写字台灯用什么牌子的好?高品质学生台灯品牌推荐