集合框架的分类
总的来说集合框架分为两大类,单列集合Collection和双列集合Map,Collection下又细分为List和Set两种单列集合,其中的Set集合基本都依赖于Map集合的实现类实现。
Collection
Collection是单列集合的顶级父类,它还实现了接口Iterator(jdk1.5+)用于对集合进行迭代遍历,除此之外,它还存在一个工具类Collections,用于实现一些集合常用的功能
常用方法:
- public void add(E e):添加指定对象到集合中
- pubic void addAll(Collection c):添加指定Collection集合到集合中
- public boolean remove(E e):删除指定元素
- public boolean removeAll(Collection c):删除指定Collection集合中包含的元素
- public void clear():清空集合元素
- public boolean contains(E e):集合是否包含指定元素
- public boolean isEmpty():集合是否为空
- public int size():集合中元素个数
- public Object[] toArray():将集合中的元素存储到数组中并返回Object数组
- public Iterator iterator():获取当前集合的迭代器对象
- public Sream stream():获取当前集合的流式处理对象(jdk1.8+)
List
Collection集合分类下的有序、允许重复元素的集合接口,因为是有序的,所以新增了很多针对索引(位置)进行操作的方法
新增方法:
- public E get(int index):获取指定索引的元素
- public E remove(int index):移除并返回指定索引的元素
- public List subList(int formIndex, int toIndex):截取指定范围的数据,返回一个List假分页
- public ListIterator ListIterator():获取一个当前有序集合的ListIterator迭代器
以下是常见实现类
ArrayList
基于数组+数组拷贝实现的有序集合,初始容量10,当容量不足时扩容至原来的1.5倍,但由于本身的数组长度不可变特性,ArrayList每次进行增删操作时都需要耗费内存创建一个新的数组对象,因此ArrayList适用于查询不适合增删操作(查块改慢),它是一个线程不安全的集合。
Vector
老式的集合类,jdk1.0就已经出现,底层实现原理和ArrayList一样,不同的是每次扩容增长至原来的2倍,同时,它也是一个线程安全的集合。不过现在它基本被CopyOnWriteArrayList代替。
CopyOnWriteArrayList
来自java.util.concurrent包,相当于线程安全的ArrayList
LinkedList
基于双向链表实现的有序集合,因此比ArrayList更适合增改操作,但是由于查找时只能从链表头部/尾部依次查找,所以查找效率要低于ArrayList(查慢改快),它是一个线程不安全的集合。
基于双向链表的特性,LinkedList新增了很多对链表头尾进行操作的方法,所以有时候也可以把LinkedList作为栈和队列结构使用
新增方法:
-
public void addFirst(E e):在头部添加指定元素
-
public void addLast(E e):在尾部添加指定元素
-
public E getFirst():获取头部元素
-
public E getLast():获取尾部元素
-
public E removeFirst():移除头部元素
-
public E removeLast():移除尾部元素
-
public void push(E e):向栈底推入元素(即头部添加元素)
-
public E pop():弹出栈顶元素(即移除尾部元素)
Set
Collection集合分类下的无序、不允许重复元素的集合接口,一旦判断重复,该元素就不会加入集合。因为是无序的,所以不存在通过索引对set集合进行操作,Set集合中的无序指的是存储顺序与添加顺序无关,不同的Set实现类会根据不同的规则存储添加的元素,不重复元素的判别标准在不同实现类中也不同。
新增方法:基本与父类接口一致
以下是常见实现类
HashSet
基于hash表的无序集合,底层依赖HashMap实现,通过调用hashCode来判断添加元素是否在列表中存在,并且根据hashCode为其指定存储位置
CopyOnWriteHashSet
来自java.util.concurrent包,相当于线程安全的HashSet
TreeSet
基于二叉树中的红黑树实现,底层依赖TreeMap实现,查重和位置指定是依赖存储元素类实现的Comparable接口,因此TreeSet的使用有2个前提:
- 元素必须是同一种数据类型
- 元素必须实现过Comparable接口(基本类型会自动装箱)
LinkedHashSet
是HashSet的子类,基于单向链表实现,链表有序,所以该类也体现有序特征(添加顺序和存储顺序一致)
List 与 Set集合的互相转换
List 转 Set
List list = new ArrayList(set);
//转换后可以对集合进行排序
Set 转 List
Set set = new HashSet(list);
//转换后可以去除原先集合中的重复元素
Collections
Collections是从jdk1.2新增的对集合进行操作的工具类,内部的所有方法都是静态
常见操作方法:
- 二分查找
- 集合的创建
- 排序
- 乱序(洗牌)shuffer()
- 反转 reverse()
- 最大/最小值(依据自然排序---->元素实现了comparable接口,根据compara中实现的规则来获取最大最小值)
- …
集合排序方法
方法 | 解释 |
---|---|
sort(List list) | 元素类实现了Comparable接口 |
sort(List list,Comparator c) | 单独构建比较器,设置排序依赖的规则 |
集合中的排序主要靠两个接口实现:
- Comparator(类外单独构建比较器)
- Comparable(类中实现该接口,主方法中通过Collections调用sort进行排序)
- Serializable可序列化
实现Comparable接口
Comparable 接口中提供了一个compareTo方法,该方法需要由排序类进行实现,根据方法内部的实现,Collections中的sort方法会依赖该实现对元素进行排序
根据compare返回的结果;
- 正数->o1大于o2,两个元素交换位置
- 0->相等,不交换
- 负数->o2大于o1,不交换
Iterator
-
实现了interable接口的类(Array Collection ArrayList…)都可以成为foreach语句的目标
-
Iterator是jdk1.5后实现的对集合进行快速遍历的接口,内部实现通常是通过内部类Itr实现
-
ListIerator是Iterator的子类,可以实现逆向迭代,仅适用于List集合
Map
Map是双列集合的顶级接口,集合中存储的元素都是键值对结构(Map.Entry<K, V>),通常以一个键来标识一个值。Map集合键不可重复,值可重复,一旦遇到键相同但值不同的元素,后续的值会覆盖之前重复建对应的值
常用方法:
方法 | 解释 |
---|---|
clear() | 清除集合中的所有元素 |
containsKey(Object Key) | 判断集合中是否包含指定的建 |
containsValue(Object Value) | 判断集合中是否包含指定的值 |
entrySet() | 返回当前Map集合中Entry的Set集合 |
get(Object key) | 根据键获取值 |
put(Object key,Object Value) | 向集合中添加元素 |
remove(Object key) | 根据键移除指定元素 |
Set keySet() | 返回集合中所有key的Set集合 |
Collection values() | 返回集合中所有value的Collection集合 |
HashMap
HashMap是最常用的Map实现类,内部基于数组+链表(1.8之后+红黑树----数组长度超过64、链表深度超过8时),HashMap不允许空键。
实现原理:
HashMap的数组初始容量(capacity)是16,默认加载因子是0.75(依据减少hash碰撞概率计算得出),根据加载因子的大小来决定出现重复位置元素后是优先扩容数组还是使用链表。默认情况下通过计算元素的hash值和16取余(hash = & lenght-1),再根据计算结果将元素(Map.Entry)存储在对应数组中,如果该位置已经存在键值不同的元素,则将新元素作为链表头部(头插)插入该位置(1.8后采用尾插法),next指向原来在这个位置的元素。
TreeMap
可以实现按照指定规则排序需求的实现类,该类内部基于红黑树(平衡排序二叉树)实现,,TreeMap不允许空键,键对应的类型重写了Comparable接口后,重写了compareTo接口才能实现,因此TreeMap的使用必须满足以下2个条件:
- Key类型必须一致
- Key对应的类必须实现Compare接口
LinkedHashMap
基于链表的HashMap实现,是HashMap的子类
- 允许空键
- 通过链表实现内部元素存储顺序与添加顺序保持一致
HashTable
继承自老式集合类java.util.Dictionary,也是一种键值对结构的集合解决方案。
与HashMap的区别
- 它的初始容量是11
- 线程安全的体现(但需要线程安全的Map建议使用下面的ConcurrentHashMap)
ConcurrentHashMap
来自java.util.concurrent包,相当于线程安全的HashMap