1.集合
什么是集合
概念:
对象的容器,提供了一些多个对象操作的方法,类似于数组。
跟数组的区别:
- 数组长度是固定的,集合长度不固定。
- 数组支持基本类型与引用类型,集合只支持引用类型。
2.Collection体系
3.Collection根接口
特点:
表示一组任意类型的对象,每个对象被称为元素,并且定义了一些常用方法。
常用方法:
boolean add(E e) | 添加指定元素到集合中 |
boolean addAll(Collection<? extends E c) | 将相同引用类型的集合中所有元素添加到当前集合 |
void clear() | 移除集合中所有元素 |
boolean contains(Object o) | 返回集合是否包含指定的对象 |
boolean containsAll(Collection<?> c) | 返回当前集合是否包含指定集合的所有元素 |
boolean equals(Object o) | 与指定对象进行比较 |
int hashCode() | 返回当前集合的哈希值 |
boolean isEmpty() | 返回集合是否不包含任意元素 |
Iterator<E> iterator() | 返回集合中的元素的迭代器 |
default Stream<E> parallelStream() | 返回一个当前集合作为数据来源的可能并行的Stream |
boolean remove(Object o) | 从集合中移除指定的元素 |
boolean remove(Collection<?> c) | 移除当前集合中包含的指定集合的所有元素 |
default boolean removeIf(Predicate<? super E> filter) | 移除当前集合中满足指定Predicate的所有元素 |
boolean retainAll(Collection<?> c) | 仅保留当前集合包含的指定集合的所有元素 |
int size() | 返回集合中元素个数 |
default Spliterator<E> spliterator() | 创建当前集合中元素的Spliterator |
default Stream<E> stream() | 返回一个当前集合作为数据来源的Stream |
Object[] toArray() | 返回包含当前集合所有元素的数组;数组类型为Object类型 |
<T> T[] toArray(T[] a) | 返回包含此集合中所有元素的数组;数组类型与元素类型相同 |
4.迭代器(Iterator)
概念:
专门遍历集合的对象。
方法:
default void forEachRemaining(Consumer<? super E> action) | 对迭代器剩余的每个元素执行指定的Consumer,直到所有剩余元素都被处理或发生异常中断 |
boolean hasNext() | 迭代器是否有下一个元素 |
E next() | 返回迭代器下一个元素 |
default void remove() | 从迭代器对应的集合中移除最后一个元素(其实是迭代器当前索引位置的元素) |
注意:
不能在使用迭代器遍历时,使用Collection.remove等可以移除元素的方法。
5.List
特点:
有序、有下标所以元素可重复。
独有方法:
List 继承自Collection,所以 List 内的方法包含了Collection接口方法,就不再赘述,见上文。
void add(int index,E element) | 在List指定位置插入指定的元素 |
void addAll(Collection<? extends E> c) | 在List指定位置插入指定集合的所有元素 |
E get(int index) | 返回指定位置的元素 |
int indexOf(Object o) | 返回在List中指定对象第一次出现的索引 |
int lastIndexOf(Object o) | 返回在List中指定对象最后一次出现的索引 |
ListIterator<E> listIterator() | 返回List的ListIterator |
ListIterator<E> listIterator(int index) | 返回List从指定索引开始的ListIterator,ListIterator包含指定索引的元素 |
E remove(int index) | 移除List指定位置的元素 |
boolean replaceAll(UnaryOperator<E> operator) | 使用UnaryOperator替换List中每个元素 |
E set(int index,E element) | 替换List中指定位置的元素 |
default void sort(Comparator<? super E> c) | 使用指定的Comparator对List所有元素进行排序 |
List<E> subList(int fromIndex,int toIndex) | 以List返回指定起始索引到终止索引见的所有元素,包含起始索引对应的元素,不包含终止索引对应的元素 |
6.List 常用实现类
ArrayList | 数组结构实现,查询快、增删慢;JDK1.2 版本支持,运行效率快、线程不安全 |
Vector | 数组结构实现,查询快、增删慢;JDK1.0 版本支持,运行效率慢、线程安全 |
LinkedList | 链表结构实现,查询慢、增删快;JDK1.2 版本支持,运行效率快、线程不安全 |
7.ArrayList
源码分析:
- static final int DEFAULT_CAPACITY 是10,是默认容量。但是如果没向集合中添加任何元素是,当前ArrayList容量为0,添加一个元素后,容量为10。
- 可以指定初始容量,在构造ArrayList时指定。
- ArrayList 每次扩容会扩容为原来的1.5倍。
- Object[] elementData 是存放元素的数组。
- int size 是实际元素个数。
8.ArrayList与LinkedList的区别
9.泛型
- Java 泛型是JDK1.5引入的一个新特性,本质是把类型参数化,即类型可以作为参数传递。
- 常见形式有泛型类、泛型接口、泛型方法。
- 语法:<T,….>T称为类型占位符,表示一种引用类型。
- 好处:提高代码的重用性;防止类型转换异常,提高代码的安全性。
10.泛型集合
概念:
参数化类型以及类型安全的集合,要求所有集合元素的类型必须一致。
特点:
- 编译时即可检查,而不会运行时抛出异常(类型不一致异常)。
- 访问,不需要强制类型转换(拆箱)。
- 不同泛型之间引用不能相互赋值,泛型不存在多态。
11.Set接口
Set 接口完全继承自Collection,没有自己独有的方法。
12.Set 实现类
HashSet | 基于HashCode实现元素不重复。 当存入元素的HashCode相同时,会调用equals进行判断,如果为true,会拒绝后者写入。 |
TreeSet | 基于排列顺序实现元素不重复。 实现了SortedSet接口,对集合元素自动排序。 元素对象的类型必须实现Comparable接口,指定排序规则。 通过CompareTo方法确定是否为重复元素。 |
13.HashSet
存储结构:
哈希表(数组+链表+红黑树)
存储过程:
先根据元素的HashCode计算存储位置,如果计算出来的存储位置没有存储对象,那么就直接存储;如果有,就调用equals方法,如果equals方法返回true,则认为重复拒绝写入,否则,形成链表。
14.TreeSet
存储结构:
红黑树。
15.Map
Map体系
Map 接口
特点:存储键值对,无序、无下标,键不可重复,值可以重复。
常用方法:
V put(K key,V value) | 将键值对存入到Map中。Key 重复会覆盖掉原值 |
Object get(Object key) | 根据键获取值 |
Set<K> keySet() | 返回所有Key |
Collection<V> values() | 返回包含所有值的Collection集合 |
Set<Map.Entry<K,V>> entrySet() | 键值匹配的Set集合 |
16.Map实现类
HashMap | JDK1.2,线程不安全,运行效率快;允许用null作为Key或Value |
Hashtable | JDK1.0,线程安全,运行效率慢;不允许用null作为Key或Value |
Properties | Hashtable 子类,要求Key和Value都必须String;通常用于资源文件的读写 |
TreeMap | 实现了SortedMap接口(是Map的子接口),可以对Key自动排序 |
17.HashMap
存储结构:
哈希表。
重复依据:键的hashCode()方法和equals()方法。
源码分析:
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; | hashMap初始容量大小 |
static final int MAXIMUM_CAPACITY = 1 << 30; | hashMap的数组最大容量 |
static final float DEFAULT_LOAD_FACTOR = 0.75f; | 默认加载因子 |
static final int TREEIFY_THRESHOLD = 8; | jdk1.8 当链表长度大于8时,调整为红黑树 |
static final int UNTREEIFY_THRESHOLD = 6; | jdk1.8 当链表长度小于6时,调整为链表 |
static final int MIN_TREEIFY_CAPACITY = 64; | jdk1.8 当链表长度大于8时,并且集合元素个数大于等于64时,调整为红黑树 |
transient Node<K,V>[] table | 哈希表中的数组 |
transient int size; | 元素个数 |
总结:
- HashMap刚创建没添加元素时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16.
- 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数。
- jdk1.8 当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的提高执行效率。
- jdk1.8 当链表长度小于6时,调整为链表。
- jdk1.8以前,链表是头插入,jdk1.8以后是尾插入。
注意:
HashSet 内部用的就是HashMap。
18.TreeMap
存储结构:
红黑树。
注意:
TreeSet 内部用的就是TreeMap。
19.Collections工具类
概念:
集合工具类,定义了集合除存取以外的集合常用方法。
方法:
public static void reverse(List<?> list) | 反转集合中元素的顺序 |
public static void shuffle(List<?> list) | 随机重置集合元素的顺序 |
public static <T extends Comparable<? super T>> void sort(List<T> list) | 升序排序(元素类型必须实现Comparable接口) |