集合
集合是Java提供的一种容器,可以用来存储多个数据.
集合分为单列集合和双列集合
单列集合
单列集合的根接口是Collection,用于存储一系列符合某种规则的元素.它有两个重要的子接口,分别是java.util.List和java.util.Set.
List接口下有ArrayList和LinkedList两个主要的实现类.
Set接口下有HashSet和LinkedHashSet两个主要的实现类.
遍历方式
迭代器和增强for
ArrayList
使用数组保存数据
特点是查询快,增删慢.
为什么查询快?
数组在内存中是连续存储的,连续存储指的是数组中的元素在内存中是相邻的.这样就可以根据数组首元素的地址值计算出其他元素的地址值啦.
为什么增删慢?
因为数组长度固定,每次增删操作都需要创建新的数组.
默认容量为10.
扩容增量是: 原容量的0.5倍+1
如初始容量为10,一次扩容后容量是16.
LinkedList
使用双向链表保存数据
特点是查询慢,增删快.
为什么查询慢?
链表在内存中是离散存储的
离散存储指的是链表的节点在内存中是没有规律的.这样如果找到一个节点,必须从前面一个个找.
为什么增删快?
如果要增删操作,只需要修改链表节点的地址值.
HashSet
底层是使用HashMap存储数据
有三个特点
一.无序
二.没有索引
三.不可重复
初始容量为16.
加载因子是0.75:当元素个数超过容量长度的0.75倍时,进行扩容
扩容增量:原容量的1倍.
如HashSet的容量为16,一次扩容后为32.
HashSet保证唯一性的方式
有两步
第一,比较两个对象的哈希值
如果哈希值不同,肯定是不同的对象
如果哈希值形同,不一定是同一个对象
第二,使用equals方法比较
如果equals方法结果是true,表示两个对象相同
如果equals方法结果是false,表示两个对象不同.
如果要保证HashMap中key的唯一性,必须重写对应的hashCode和equals.
LinkedHashSet
内部使用哈希表+链表存储数据.可以保证有序.
Set接口是无序的,但是他不能保证所有的实现类都无序.
双列集合
双列集合的根接口是Map,下面主要有三个实现类HashMap,Hashtable,TreeMap
它里面的每一个元素都是一个键值对.键不能重复,值允许重复.
我们可以根据键的值找到value的值.
遍历方式
keySet
拿到Map集合中的所有的key, 把所有的key放入到一个Set集合, 遍历 这个Set集合
拿到里面的每一个key,根据key获取对应的value。
entrySet
获取到Map集合中的所有的Entry对象并放入到Set集合。然后再进行遍历。
Entry中,获取键和值的方法:
K getKey(): 获取Entry对象中的键
V getValue(): 获取Entry对象中的值。
HashMap
初始容量为16.
加载因子是0.75:当元素个数超过容量长度的0.75倍时,进行扩容
扩容增量:原容量的1倍.
如HashSet的容量为16,一次扩容后为32.
HashMap保证唯一性的方式
有两步
第一,比较两个对象的哈希值
如果哈希值不同,肯定是不同的对象
如果哈希值形同,不一定是同一个对象
第二,使用equals方法比较
如果equals方法结果是true,表示两个对象相同
如果equals方法结果是false,表示两个对象不同.
如果要保证HashMap中key的唯一性,必须重写对应的hashCode和equals.
LinkedHashMap的特点
底层是哈希表+链表,可以保证有序.
HashMap和HashTable的区别
- HashMap键和值允许为空值,HashTable不允许为空值.
- HashMap非线程安全,HashTable基于Synchronized,线程安全
- HashMap非同步,适用于单线程,HashTable同步,适用于多线程.
- HashMap效率高速度快,HashTable效率低.
ConcurrentHashMap与HashTable的区别
- ConcurrentHashTable使用锁分段技术保证线程安全,HashTable使用Synchronized保证线程安全
- ConcurrentHashTable采用的锁机制是一次锁住一个桶,ConcurrentHashTable默认将Hash表分为16个桶,可以同时有16个写线程执行,大大提高了并发性能.HashTable采用的锁机制是一次锁住整个哈希表.