java集合体系结构总结

好,首先我们根据这张集合体系图来慢慢分析。大到顶层接口,小到具体实现类。
首先,我想说为什么要用集合?简单的说:数组长度固定,且是同种数据类型。不能满足需求。所以我们引入集合(容器)来存储任意数据类型的可变大小的数据。
来了解下数组:
数组有静态、动态之分。但是其长度都是固定的,并且其内部只能存储同一种数据类型的数据。除非是Object类型的数组,它可以存储任意类型的数据。
数组的存储方式?数据存储结构分为顺序存储、链接存储、索引存储、散列存储。
数组是基于顺序存储方式。数组就是在内存中开辟一块连续的、大小相同的空间,用来存储数据。
数组查询速度快:因为基于索引查询。但是增删慢。为什么增删慢呢?因为数组的元素是连续的(索引是连续的)。如果要增删元素时,会发生索引位置的移动,且是重新创建了一个新数组。所以增删慢。


java集合体系结构中主要按两种接口分类:
1.Collection
2. Map
//查看jdk1.8源码
首先分析Collection,它是一个接口,同时它继承了顶级Iterable接口,为什么要继承这个接口呢?主要是使用接口中特有
方法,可以通过iterator迭代器遍历整个集合。在jdk1.8中,Iterable接口中有forEach方法、spliterator()方法。
同时,List接口继承了Collection接口.List是存取有序可重复且有索引的,同时允许元素为null。这里所说的有序是元素的存取顺序。而Set是无序不可重复无索引。但是Set的无序我们一般是指HashSet,因为它不能保证元素的存取顺序和自然排序。而LinkedHashSet:保证元素的添加顺序。TreeSet:保证元素的自然排序。可能知道的人很容易理解,不知道的人不理解就很难记忆。通过代码,也可以清楚看到是否有序,是否重复的特性。由于篇幅,演示代码省略。接下来我们逐一分析接口下的实现类都有什么特性?
List接口下的实现类
ArrayList:底层是使用了Object数组实现的,查询速度快,增删慢。非同步的(线程不安全类),因此效率高。数组默认容量是10,当长度不够时自动增长0.5倍,也就是原数组的1.5倍。
使用场景:频繁查询时,增删较少时。
LinkedList:底层结构是双向链表,不需要在内存中开辟一段连续的内存空间。而是每个元素有一个下一元素地址]这样的内存结构。增加时只需要改变两个节点之间的引用关系即可。来组成一个新的节点。删除时只要删除两个节点的引用即可。而查询时,必须从头部开始查询。所以效率慢。查询慢,增删快。同时它是非同步的(线程不安全类)。https://blog.csdn.net/qq_35120695/article/details/56573865
Vector: 底层也是基于动态数组实现。线程安全类,但是效率低,基本不使用。
Set接口下的实现类


HashSet:底层数据结构是哈希表,而jdk1.8中哈希表底层采用数组+链表+红黑树。其实现set接口,底层使用HashMap来保存所有元素。特点:无序不可重复。线程不安全。其是如何保证去重原理的呢?
从源码中我们可以看出:
它的add()方法实际上调用的是HashMap中的put()方法,把要添加进HashSet中的元素当做key存入,而value则是一个固定值:一个Object类对象。
先用hashCode()方法获得传入元素的哈希值,在集合中查找是否包含哈希值相同的元素,如果相同,则继续进行比较它们地址值,一般地址值都是不相同的,所以最后会用equals()方法比较对象内的属性值。
比较结果全为false就存入,如果比较结果有true则不存。

TreeSet:底层使用TreeMap来进行存储,而TreeMap底层基于红黑树数据结构,规则是左小右大。有序不可重复。有序指对元素进行自然排序。同时支持定制排序。线程不安全类。
红黑树规则补充:
红黑树:也可以叫二叉树
规则:左节点小于等于父节点,右节点大于父节点。
为了保证树的左右平衡,红黑树采用节点标色的方式,将节点标记为红色或黑色。根节点(没有父节点)为黑色。
每个叶子节点都是null值且是黑色。
如果一个节点为红色,则它的子节点必须是黑色
新插入节点的颜色为红色
左旋,右旋、颜色反转操作保持树平衡
jdk1.8中加入红黑树目的就是解决链表的查询效率低的问题。
HashMap默认容量是16,源码显示1<<4,就是1向左移动4为,即为16.
当链表长度>8时,则将链表转为红黑树。
当红黑树内数量<6时,将红黑树转为链表
TreeSet注意事项:
1、往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素本身的自然顺序特性进行存储;
2、如果元素本身不具备自然 顺序的特性,那么该元素所属的类必须要实现Comparable接口,并重写compareTo()
方法,把元素的比较规则定义在compareTo()方法上;
3、如果比较元素的时候,compareTo()方法返回的是0,那么该元素就被视为重复元素,不允许添加;
LinkedHashSet:底层是哈希表和链表。其继承了HashSet,实现set接口。
由链表保证元素的有序(存取顺序)。由哈希表保证元素的唯一(不重复)。内部是通过 LinkedHashMap 来实现的。
Map接口下的实现类
HashMap:首先看源码分析,它继承了AbstractMap类,基于哈希表的Map接口实现。是以key-value存储形式。主要用来存放键值对。它是非同步(线程不安全)的。它的key-value都可以为null,且映射是无序的。
jdk1.8之前,HashMap由数组+链表组成。数组是主体,链表则是主要为了解决哈希冲突(两个对象通过hashcode方法计算的哈希码值一致导致数组索引值相同)而存在的。
在jdk1.8之后,当链表长度大于阈值(红黑树的边界值默认为8)并且当前数组长度大于64时,此时所有数据改为采用红黑树存储。
补充:将链表转为红黑树前会进行判断,即使阈值大于8,但是数组长度小于64,此时并不会将链表转为红黑树,而是进行数组扩容。这样做的目的是因为数组长度比较小,尽量避开红黑树结构。因为这种情况下使用红黑树结构反而效率低,因为红黑树需要通过左旋、右旋、变色等操作来保持平衡。同时数组长度小于64时,查询时间更快些。

特点:
- 存取无序
- 键值位置都可以为null,但是键位置只能是一个null且键唯一。
- jdk1.8之前数据结构是数组+链表。jdk1.8之后是:数组+链表+红黑树。
- 当链表长度大于8,并且数组长度大于64时,将链表转为红黑树,目的是提高查询效率
Hashmap的存储过程如下图:









如果创建集合时,我们用有参构造,指定初始容量不是2的n次幂情况分析
查看底层算法如下:


如果指定初始容量不是2的n次幂,底层会进行一顿右移和或运算。


















TreeMap:
通过红黑树实现,默认情况下通过Key值的自然顺序进行排序,也可以通过比较器排序。非线程安全类
https://www.cnblogs.com/LiaHon/p/11221634.html
HashTable:


HashMap可以允许存在一个为null的key和任意个为null的value,但是HashTable中的key和value都不允许为null.而当HashTable遇到null时,他会直接抛出NullPointerException异常信息。
Hashtable的方法是同步(线程安全,效率低)的,而HashMap的方法不是。所以有人一般都建议如果是涉及到多线程同步时采用HashTable,没有涉及就采用HashMap。
HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
https://blog.csdn.net/varyall/article/details/80992123
CurrentHashMap
https://www.cnblogs.com/supertang/p/4149786.html
扩容图示:

java集合体系结构总结的更多相关文章
- Java集合体系结构(List、Set、Collection、Map的区别和联系)
Java集合体系结构(List.Set.Collection.Map的区别和联系) 1.Collection 接口存储一组不唯一,无序的对象 2.List 接口存储一组不唯一,有序(插入顺序)的对象 ...
- -1-3 java集合框架基础 java集合体系结构 Collection 常用java集合框架 如何选择集合 迭代器 泛型 通配符概念 Properties 集合 迭代器
集合又称之为容器存储对象的一种方式 •数组虽然也可以存储对象,但长度是固定的:显然需要可变长度的容器 集合和数组的区别? A:长度区别 ...
- Java基础之 集合体系结构(Collection、List、ArrayList、LinkedList、Vector)
Java基础之 集合体系结构详细笔记(Collection.List.ArrayList.LinkedList.Vector) 集合是JavaSE的重要组成部分,其与数据结构的知识密切相联,集合体系就 ...
- JAVA集合介绍
一.集合概述 Java是一种面向对象语言,如果我们要针对多个对象进行操作,就必须对多个对象进行存储.而数组长度固定,不能满足变化的要求.所以,java提供了集合. 特点 1. 长度可以发 ...
- JAVA集合小结
下面是我自己画的,关系画得没上面好,但我自己看着清楚些 还有一张下载来的: 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否 否 Hash ...
- 【转】Java集合框架List,Map,Set等全面介绍
原文网址:http://android.blog.51cto.com/268543/400557 Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含 ...
- Java集合初体验
背景: 因为对Java的集合完全不了解,所以才在网上找了找能形成初步印象的文章进行学习,大多涉及的是一些概念和基础知识. 一.数组array和集合的区别: (1)数组是大小固定的,并且同 ...
- 1.Java集合总结系列:Java集合概述
一.概述 集合是 Java 中非常重要的 API,在实际应用中非常广泛,在许多面试中也是必考的知识点. Java 所有集合类都位于 java.util 包下,Java 的集合只能保存对象,而无法保存保 ...
- Java集合框架梳理(含经典面试题)
Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含一组接口,类的体系结构. 1. 整体框架 Java容器类库一共有两种主要类型:Collection ...
随机推荐
- 常用的MQ命令
删除队列管理器 dltmqm QmgrName 启动队列管理器 strmqm QmgrName 如果是启动默认的队列管理器,可以不带其名字 停止队列管理器 endmqm QmgrName 受控停止 e ...
- Codeforces Round #599 (Div. 2) B2. Character Swap (Hard Version)
This problem is different from the easy version. In this version Ujan makes at most 2n2n swaps. In a ...
- java到js的中文无法显示,中文显示位(?)
今天遇到这么一个问题,用js调用java的get请求,得到的json数据中中文无法正常显示,jsp文件中都是申明utf-8格式的,查询了一番,发现问题出现在@ResponseBody上 @Respon ...
- ISE-Backup Data Type
Cisco ISE allows you to back up data from the Primary PAN and from the Monitoring node. Back up can ...
- 编译原理--05 用C++手撕PL/0
前言 目录 01 文法和语言.词法分析复习 02 自顶向下.自底向上的LR分析复习 03 语法制导翻译和中间代码生成复习 04 符号表.运行时存储组织和代码优化复习 05 用C++手撕PL/0 在之前 ...
- linux默认的目录结构
/: 根目录/root: root账户的home目录/home: 用户的目录,每个用户有一个home/bin: 可执行文件和命令/lib: 库文件/etc: 配置文件存放地/usr: 用户的应用程序和 ...
- idea项目更改git地址
第一步:idea打开项目,菜单栏找VCS - Git - Remotes 点进去,弹出对话框,选中,点击编辑 弹出编辑框,更改地址,点击ok 弹出输入账号密码编辑框,输入自己的账号密码,点击确认 完成 ...
- sqlserver查询使用with(nolock)详解
所有Select加 With (NoLock)解决阻塞死锁 在查询语句中使用 NOLOCK 和 READPAST 处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAS ...
- 【PAT甲级】1076 Forwards on Weibo (30 分)
题意: 输入两个正整数N和L(N<=1000,L<=6),接着输入N行数据每行包括它关注人数(<=100)和关注的人的序号,接着输入一行包含一个正整数K和K个序号.输出每次询问的人发 ...
- 3 爬虫cookie的处理办法
cookie的应用和处理 - cookie:服务器端记录客户端的相关状态 - 处理cookie的方式: - 手动处理:不建议 页面找隐藏的标签,获取value - 自动处理:会话对象Session,该 ...