Java容器-单例集合
1.容器简介
容器类似于显示生活中的锅碗瓢盆,可以存放东西。
在Java中,数组可以用来存放基本类型数据或者对象,但是随着深入的学习,数组的弊端也显现出来了,不能随着需求变化尽心扩容。所以实际中我们其实使用集合(Collection)来装载我们的对象。
2.单例集合
2.1 基本介绍
将数据一个一个的进行存储。

2.2 Collection接口
是单例集合根接口,继承自超级接口Iterator,定义了所有单例集合的共性接口。
方法
基本方法
- int size();
- boolean isEmpty();
- boolean contains(Object element); 是否包含指定元素
- boolean add(E element); 添加元素,成功时返回 true
- boolean remove(Object element); 删除元素,成功时返回 true
- Iterator
iterator(); 获取迭代器
操作集合的方法
- boolean containsAll(Collection<?> c) ;
是否包含指定集合 c 的全部元素 - boolean addAll(Collection<? extends E> c) ;
添加集合 c 中所有的元素到本集合中,如果集合有改变就返回 true - boolean removeAll(Collection<?> c) ;
删除本集合中和 c 集合中一致的元素,如果集合有改变就返回 true - boolean retainAll(Collection<?> c) ;
保留本集合中 c 集合中两者共有的,如果集合有改变就返回 true - void clear() ;
删除所有元素
操作集合变数组的方法
- Object[] toArray() ;
返回一个包含集合中所有元素的数组 T[] toArray(T[] a) ;
返回一个包含集合中所有元素的数组,运行时根据集合元素的类型指定数组的类型
2.3 List接口
继承Collection接口,有几个特点
- 有序
- 可重复
- 可以存储null值
- 有索引,针对每个元素可以快速的查询和修改
方法
增加
- void add(int index, E element)
在指定 index 索引处理插入元素 element - boolean addAll(int index, Collection<? extends E> c) 在指定 index 索引处理插入集合元素 c
删除
- E remove(int index)
删除指定索引 index 处的元素
修改
- E set(int index, E element)
修改指定索引 index 处的元素为 element
获取
- E get(int index)
获取指定索引处的元素 - int indexOf(Object o)
从左往右查找,获取指定元素在集合中的索引,如果元素不存在返回 -1 - int lastIndexOf(Object o)
从右往左查找,获取指定元素在集合中的索引,如果元素不存在返回 -1 - List
subList(int fromIndex, int toIndex)
截取从 fromIndex 开始到 toIndex-1 处的元素
遍历
- ListIterator
listIterator()
通过列表迭代器遍历集合中的每一个元素 - ListIterator
listIterator(int index)
通过列表迭代器从指定索引处开始正向或者逆向遍历集合中的元素
2.3.1 ArrayList
ArrayList 是 List 接口的实现类。是 List 存储特征的具体实现。
ArrayList 底层是用数组实现的存储。 特点:查询效率高,增删效率低,线程不安全。
实例
点击查看代码
public static void main(String[] args) {
List<String> a = new ArrayList<>();
a.add("aa");
a.add("bb");//添加元素
for (int i = 0; i < a.size(); i++) {
System.out.println(a.get(i));//获取指定索引出的元素
}
String first = a.get(0); //获取指定索引出的元素
a.remove(0);//删除指定位置的元素
a.remove("aa");//删除指定元素
String second = a.set(1,"cc");//替换指定索引的元素
a.clear();//清空容器
boolean isEmpty = a.isEmpty();//判断容器是否为空
boolean flag = a.contains("aa");//判断列表中是否包含指定的元素
int flag1 = a.indexOf("aaa");//判断指定元素第一次出现的位置
int flag2 = a.lastIndexOf("aaa");//判断指定元素最后一次出现的位置
Object[] flag3 = a.toArray();//单例集合转化为object数组
String[] flag4 = a.toArray(new String[a.size()]);//转换泛型类型数组
List<String> b = new ArrayList<>();
b.add("bb");
b.add("cc");
boolean flag5 = a.addAll(b);//取并集
boolean b1 = a.retainAll(b);//取交集
a.removeAll(b);//取差集
}
源码分析
底层是用数组实现的存储

无参构造初始化,是一个空数组

当调用add()方法时会对数组先进行扩容

容量检查,确认数组是否需要扩容

数组的扩容逻辑(1.5倍)

2.3.2 VecTor
Vector 底层是用数组实现的,相关的方法都加了同步检查,因此“线程安全,效率低”。 比如,indexOf 方法就增加了 synchronized 同步标记。
例如

源码分析
初始化的时候定义了数组长度

判断是否需要扩容

扩容逻辑

2.3.3 LinkedList
LinkedList底层用双向链表实现的存储。特点:查询效率低,增删效率高,线程不安全。
双向链表也叫双链表,它的每个数据节点都有两个指针,分别指向前一个结点和后一个节点。所以从双向表的任意一个节点开始,都可以方便的找到所有的节点。
class Node{ E item; Node<E> next; Node<E> prev; }
方法(扩展List):
- void addFirst(E e) 将指定元素插入到开头
- void addLast(E e) 将指定元素插入到结尾
- getFirst() 返回此列表的第一个元素
- getLast() 返回此列表的最后一个元素
- removeFirst() 移除此列表中的第一个元素,并返回这个元素
- removeLast() 移除此列表中的最后一个元素,并返回这个元素
- E pop() 从此列表所表示的堆栈处弹出一个元素,等效于removeFirst
- void push(E e) 将元素推入此列表所表示的堆栈 这个等效于 addFisrt(E e)
- boolean isEmpty() 判断列表是否包含元素,如果不包含元素则返回 true
源码分析
节点类

成员变量

添加元素
- 头尾添加元素,直接改变头尾的指针引用

- 指定位置添加元素,先判断是否抛异常,接着找到当前位置节点,最后插入节点



获取元素


删除元素


2.4 Set
Set接口继承自Collection,Set接口中没有新增方法,意味着和Collection保持一致。
常用的实现类有:HashSet、TreeSet等。
特点
- 无序, Set 中的元素没有索引,我们只能遍历查找.
- 不可重复,不允许加入重复的元素。更确切地讲,新元素如果和 Set 中某个元素通过 equals() 方法对比为 true,则只能保留一个(需要自定义HashCode和equals方法)。
2.4.1 HashSet
特征
- 无序
HashSet 是一个没有重复元素的集合,不保证元素的顺序。在 HashSet 中底层是使用 HashMap 存储元素的。HashMap 底层使用的是数组与链表实 现元素的存储。元素在数组中存放时,并不是有序存放的也不是随机存放的,而是对元素的哈希值进行运算决定元素在数组中的位置。 - 不重复
当两个元素的哈希值进行运算后得到相同的在数组中的位置时,会调用元素的 equals() 方法判断两个元素是否相同。如果元素相同则不会添加该元素,如果不相同则会使用单向链表保存该元素。
源码
成员变量,底层使用的HashMap

使用过程中,HashMap中的value是没有使用到的,存的是一个空对象。

2.4.2 TreeSet
特点
TreeSet 是一个可以对元素进行排序的容器。底层实际是用 TreeMap 实现的,内部维持了一个简化版的 TreeMap,通过 key 来存储 Set 的元素。 TreeSet 内部需要对存储的元 素进行排序,因此,需要给定排序规则。
排序规则实现:
- 通过元素自身实现比较规则。
类需要实现Comparable接口。重写compareTo方法,自定义比较规则。 - 通过比较器指定比较规则。
通过比较器定义比较规则时,需要我们单独创建一个比较器,比较器需要实现Comparator接口的compare方法来定义比较规则,在实例化 TreeSet 时将比较器对象交给 TreeSet 来完成元素的排序处理。此时元素自身就不需要实现比较规则了。

源码
成员变量和构造方法

添加元素,只用到了map的key


浙公网安备 33010602011771号