首先说集合前,就不得不说到有相似存储功能的数组
两者的共同点在于都能存储数据,而差别在于诸多细节
1.数组的长度是定长的,而集合的长度可以根据需求,动态操作更新。
2.数组的存储内容类型要求一致,而集合中可以存储不同数据类型,但只能存储应用数据类型。
3.数组是有序的,可以根据索引进行操作,而集合不同,有些集合是有序的,有些集合是无序的。
4.数组可以存储重复相同的数据,但集合有些可以存储,有些不可以存储。
集合有两个老大,一个是Collection,一个是Map,Collection有两个小弟,一个是List,一个是Set。
首先来说List
List名下有三员常出现的大将
1.ArrayList
ArrayList
允许所有元素,包括null
底层结构:数组
线程:不同步
特点
根据索引查询效率高,增删效率低
应用场景
适合应用于大量做查询,少量做增删
初始容量10
扩容机制
增长量小于原容量一半时,扩容原容量的一半
增长量大于原容量一半时,扩容增长量
通过调用 Arrays.copyof实现
2.Vector
Vector
底层结构:数组
线程:同步
初始容量10
扩容机制
如果有指定每次扩容的容量,按指定的扩容,如果没有指定,扩容至两倍
3.LinkedList
LiknkedList
底层结构:双向链表
数据以节点为单位
单向链表只关注链表头
双向链表关注链表头和链表尾
链表本身不存在索引,但链表中的数据是有序的,所以可以模拟索引
特点
查询效率低,增删效率高
应用场景
大量增删,少量查询
相较之其他有一个特殊的遍历方式:descendingIterator();反向迭代
遍历方式
for
foreach
iterator
ListIterator
随后是Set手下有两员大将
1.HashSet
HashSet
底层结构
哈希表
数组+链表:jdk7之前
数组+链表+红黑树:jdk8以后
是由HashMap维护的
特点
查询增删效率都较高
数组汇总存放链表的首节点
应用场景
适合应用在大量查询增删的情况
2.Treeset
TreeSet:无序去重,不同步不安全
底层结构
红黑树(平衡二叉树)
特点
自动做升序排序
应用场景
想要对数据做升序|降序排序的情况
遍历方式
foreach
iterator
如何定义比较规则
内部比较器|自然排序|默认比较规则
需要比较的类实现Comparable接口,重写compareTo(T o)方法
Comparable<E>
E一般为本类型
TreeSet的去重与排序,都根据调用的比较器返回值
x.compareTo(y)
0 ----->x=y
<0 ----->x<y
>0 ----->x>y
Double.compare(a,b)
结合compareTo实现升序
外部比较器|定制排序|自定义比较规则
实现Comparator接口的类
有传递外部比较器的话以外部比较器为主,没有就找内部比较器,都没有就报错
可以使用匿名内部类简化
以及使用lambda表达式简化
在之后,就是另外一名老大和他的手下
Map
键值对的集合,映射的集合
Key-Value
Key:唯一的,无序的
Set
Value:无序的,可重复的
Collection
Map接口下所有的去重与无序,都是根据键值对的key实现的
添加相同的Key,Value会覆盖前者
遍历方式
Collection<V> values() 获取所有的value返回
Set<K> keySet() 返回此映射中包含的键的Set视图。
Set<Map.Entry<K,V>> entrySet() 返回此地图中包含的映射的Set视图。
1.TreeMap
TreeMap
底层结构
红黑树
特点
根据键值对的key做升序排序
去重和排序,都是根据key来实现
去重:通过put添加,key相同时,value覆盖
新增方法
一些比较大小的方法
遍历方法
values
keyset
map.entry
2.HashMap
HashMap
初始容量(底层数组的容量
16
加载因子(计算扩容阈值)
0.75F
阈值(扩容临界值)
容量*加载因子
扩容机制
每次扩容至原容量的两倍
继承自java.util.AbstractMap<K,V>
允许null值
线程不安全|不同步
底层结构
哈希表
如何处理HashMap线程不安全的问题
Hashtable
collections ---->synchronizedMap(Map<K,V> m)
juc ---->concurrentHashMap<K,V>推荐
3.Hashtable
Hashtable
继承自java.util.Dictionary<K,V>
不允许null值
线程安全|同步
初始容量(底层数组的容量
11
扩容机制
每次扩容至原容量的两倍+1
4.Properties
Properties
表示一组持久的属性
可以保存到流中或从流中加载
void store(OutputStream out, String comments)
//将此Properties表中的属性列表(键和元素对)以适合使用load(InputStream)方法加载到Properties表的格式写入输出流。
void load(InputStream inStream)
//从输入字节流中读取属性列表(键和元素对)。
属性列表中的每个键,以及它所对应的值,都是一个个字符串
一般使用Properties的作用,都是从配置文件中加载键值对的数据