java数据存储、集合博大精深学习完,对您面试和工作事半功倍!!!

1,013 阅读6分钟

数组
存储相同类型的多个数据的结构体,长度固定
语法格式:数据类型[] 变量名=new 数据类型[长度];
一维数组和多维数组
索引从0开始,长度固定,只能存储一种类型的数据
Collection集合
子接口:List和Set,默认实现迭代器接口
List接口
存储一组有序的,可以重复的元素,允许为null
Arraylist:(线程不安全)
底部是一个Object类型的数组
初始容量 jdk1.7---10 jdk1.8---0  扩容1.5倍(通过创建新数组实现)
底层数据结构:动态数组
源码解析
扩容机制:ArrayList类帮我们维护一个为空的数组,当我们第一次赋值,数组长度改为10,当我们添加第11个元素,扩容1.5倍,通过重复复制数组实现,需要移动元素
Arraylist的内部实现是基于基础的对象数组的,因此,他的访问速度比LinkedList快,LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端。
Arraylist 查询快,增删慢
LinkedList 查询慢,增删快
LinkedList:
双链式结构 每个只关注前一位和后以为
模拟栈和队列
双向链表
1.没有初始大小,没有上限大小,空间不连续,数据有序号,严格说没有下标
2.增删快,因为不需要移动元素,查询慢,因为数据结构为双向链表不能直接根据序列号获取一个元素,必须从前往后或者从后往前进行遍历
3.允许元素为null,可以重复;
4.线程不安全
5.空间不连续,但是有序号,序号从0开始,一次累计
迭代器去遍历Arraylist和LinkedList一样快
一般情况下LinkedList占用空间更大,但是当ArrayList刚好到临界值的时候,会自动扩容到1.5倍(还是没有LinkedList占用空间多).但是ArrayList使用的是连续的内存空间,对CPU缓存更为友好.
Vector:
线程安全  方法都是同步方法
初始10,扩容2倍,效率低于ArrayList
Set接口
无序(添加顺序),不可重复
存储一组唯一,无序的对象
HashSet --- 哈希算法 比较的过程 先计算哈希值在比较equals
无序,线程不安全,允许元素为null,不能重复
底层是维护的一个HashMap 因为HashMap的key刚好符合HashSet的需求
HashSet去重复的原理?
如果两个对象equals比较为true且hashCode相同 则认为是重复的,否则不是重复的
TreeSet --- 一个有序的Set集合 顺序是元素比较的顺序
红黑二叉树 元素可排序 实现比较器接口
查询快、元素有序、元素不可重复
Comparable(compareTo)和Compartor(compare)
LinkedHashSet --- 有序的Set集合 顺序是插入的顺序
Map集合
Map<K,V>双泛型,K唯一,V可重复
HashMap
查询快,元素无序,key值不允许重复但是可以为null,value可以重复
底层数据结构: jdk1.8之前: 数组(主)+单链表 (拉链结构)
jdk1.8之后:数组(主)+单链表+红黑二叉树
当链表长度超过8、数组长度超过64的时候,链表将转换为红黑树
JDK1.8之前采用的是头插法插入数据,JDK1.8采用的尾插法插入数据。
头插法:在元素的头部插入,相对简便,但插入的数据与插入的顺序相反
每一个新节点的next始终指向头结点的next; 会产生链表成环
尾插法:在元素的尾部插入,操作相对复杂,但插入的数据与插入顺序相同
JDK1.8之前采用的哈希表+单向链表,当链表中的元素较多的时候,hash值相同的元素就多了,再次通过hash值查询的时候,效率比较低
JDK1.8之后采用哈希表+单向链表+红黑树,当链表的长度超过8的时候,就会采用红黑树去存储
红黑树:(1)每个节点或者是黑色,或者是红色
(2)根节点是黑色
(3)每个叶子节点(nli)是黑色。(注意:这里叶子节点,是指为空(nli)的叶子节点)
(4)如果一个节点是红色的,则它的子节点必须是黑色的(也就是不能连续的两个红色节点)
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点
存储数据的过程:
1.根据key计算出hash值,在加上一些扰动算法,最终得出当前元素应该存放的数组的位置
a.数组默认长度为16
b.负载因子 0.75 表示数组的使用率达到百分之75 就扩容数组 扩容2倍 resize();
2.根据key值计算出存储在数组的中的位置,如果数组中已经有值,那么向下延伸为单向链表
3.如果链表的长度大于8 并且集合中的元素个数大于64 那么链表将转换为红黑树 以此来缓解单向链表查询慢的问题
put方法的源码:
调用哈希函数获取Key对应的hash值,再计算其数组下标;如果没有出现哈希冲突,则直接放入数组;如果出现哈希冲突,则以链表的方式放在链表后面;如果链表长度超过阀值( TREEIFY THRESHOLD==8),就把链表转成红黑树,链表长度低于6,就把红黑树转回链表;如果结点的key已经存在,则替换其value即可;
扩容:如果集合中的键值对大于12,调用resize方法进行数组扩容
冲突:
HashTable
线程安全的 基于字典实现键值对存储
Properties是HashTable子类,持久化键值对文件类
HashMap与Hashtable的区别?
HashMap是线程不安全的,允许有一个key为null值,value可以有多个空值(key和value都允许)
初识容量数组长度为16,扩容2倍 resize(),JDK1.2
Hashtable是线程安全的,不允许有null值(key和value都不允许)
初识容量数组长度为11,扩容2倍+1 rehash(),JDK1.0
ConCurrentHashMap
JDK1.7:分段式锁
JDK1.8:CAS + synchronized+volatile  
特点:线程安全,查询快,元素无序,key不允许重复,key、 value不允许为null
put方法: CAS 尝试写入,失败则自旋,synchronized 锁写入数据,如果大于TREEIFY_THRESHOLD(由链表转换成树的阈值) 则要转换为红黑树
数据结构
数组
链表
二叉树
算法
查找算法
顺序查找
二分查找-折半查找
排序算法
冒泡排序
快速排序
面试题
1.HashMap的底层数据结构,jdk1.8为什么使用红黑树
使用红黑树提高了性能
2、Collection和Collections的区别
Collection是集合类的父级接口,下边实现的有set list集合
Collections是集合类的一个辅助工具类,可以帮助实现集合类的排序,反转,搜索,线程安全化等一系列功能操作
3、Comparable和Comparator接口的区别
(1) Comparable的接口只实现了compareTo方法,Comparator接口中有compareTo方法和equals方法
(2) Comparable接口需要在一个实体类上实现,重写其compareTo方法,然后调用了Arrays.sort(对象数组),然后这个对象数组的就会根据重写的compareTo方法来排序,Comparator接口是在Collections里边的使Collections.sort(list集合,new CompareTo(){重写这个方法})就会给list集合排序\