一、集合
1、 概述
集合是用来存储引用类型数据的容器
集合中只能存储对象
Java中的集合可以分为两大类:
Collection集合, 存储时是一个一个存储的
Map集合, 是按<键,值>对的形式,一对一对存储的
二、Collection集合
1、
2、Collection集合常用方法
返回值 | 方法描述 |
---|---|
boolean | add(E e) 向集合中添加元素e |
boolean | addAll(Collection<? extends E> c) 把集合c中的所有的元素都添加到当前集合中 |
void | clear() 清空集合 |
boolean | contains(Object o) 判断当前集合中是否包含元素o |
boolean | containsAll(Collection<?> c) 判断当前集合是否包含集合c中的所有元素 |
boolean | equals(Object o) |
int | hashCode() |
boolean | isEmpty() 判断集合是否为空 |
Iterator< E > | iterator() 返回集合的迭代器 |
boolean | remove(Object o) 在当前集合中移除第一个与o一样的元素 |
boolean | removeAll(Collection<?> c) 在当前集合中把c集合中的元素都移除 |
boolean | retainAll(Collection<?> c) 在当前集合中删除元素, 只保留在c集合中存在的元素 |
int | size() 返回元素的个数 |
Object[] | toArray() 集合转数组 |
< T > T [] | toArray(T[] a) |
3、注意:
(1)创建集合对象,如果没有使用泛型, 集合中元素的类型是Object类型
(2)一般情况下,集合中存储同一类型的元素, 在创建集合时,通过泛型约束元素的类型
(3)Collection是一个接口,需要指向实现类对象, 如果Collection指向ArrayList/LinkedList/HashSet等集合时, 在执行contains()/remove(E)时会调用对象的equals()方法, 元素的类型需要重写equals()
(4)通过iterator()获得当前集合的迭代器对象, hasNext()判断是否还有下一个元素,不移动游标; next()把下个元素返回, 游标下移
(5)在迭代过程 中, 不能通过集合的add()/remove()增删元素
三、List集合
1、
List接口继承了Collection接口, 就继承了Collection的所有操作
List集合存储特点: 有序, 可重复
List集合为每个元素指定了一个索引值, 主要增加了针对索引值的一些操作
2、常用方法
返回值 | 方法描述 |
---|---|
void | add(int index, E element) 在指定的位置添加元素 |
boolean | addAll(int index, Collection<? extends E> c) |
E | get(int index) 返回指定位置的元素 |
int | indexOf(Object o) 返回元素在集合中第一次出现的位置 |
int | lastIndexOf(Object o) 返回元素在集合中最后一次出现的位置 |
ListIterator< E > | listIterator() 返回列表迭代器 |
E | remove(int index) 删除指定位置的元素 |
E | set(int index, E element) 修改指定位置的元素 |
void | sort(Comparator<? super E> c) 排序 |
List< E > | subList(int fromIndex, int toIndex) 返回[fromIndex, toIndex)范围内的子列表 |
3、注意:
(1)List的每个元素都有索引值, 在使用时,需要注意索引值不能越界
(2)listIterator不仅可以向后迭代,还可以向前迭代, 添加/修改元素
(3)可以对List集合进行操作, sort(Comparator)指定比较器
(4)subList()取子列表,并没有生成新的列表 ,sublist是List列表的一个子视图, 对subList的操作实际上就是对List的操作
4、ArrayList
底层是通过数组实现的
特点: 访问快,添加/删除元素效率低
(1)ArrayList数组默认初始化容量为10
(2)ArrayList数组默认按 1.5 倍大小扩容
(3)remove()/contains()会调用对象的equals()方法
(4)iterator()方法在迭代过程中,不能通过arrayList的remove()/add()增删元素
5、Vector
底层是数组
(1)默认数组初始化容量: 10
(2)数组扩容默认按 2 倍大小扩容
(3)Vector是线程安全的, 使用synchronized修饰了它的操作方法
6、LinkedList的常用方法
主要增加了针对头元素与尾元素的操作
返回值 | 方法描述 |
---|---|
void | addFirst(E e) 在头部添加元素 |
void | addLast(E e) 在尾部添加元素 |
Iterator< E > | descendingIterator() 逆序迭代 |
E | element() 返回头元素 |
E | getFirst() 返回头元素 |
E | getLast() 返回尾元素 |
boolean | offer(E e) 在尾部添加元素 |
boolean | offerFirst(E e) 在头部添加元素 |
boolean | offerLast(E e) 在尾部添加元素 |
E | peek() 返回头元素 |
E | peekFirst() 返回头元素 |
E | peekLast() 返回尾元素 |
E | poll() 删除头元素,并把删除的头元素返回 |
E | pollFirst() 删除头元素,并把删除的头元素返回 |
E | pollLast() 删除尾元素,并把删除的尾元素返回 |
E | pop() 删除头元素,并把删除的头元素返回 |
void | push(E e) 在头部添加元素 |
E | removeFirst() 删除头元素,并把删除的头元素返回 |
E | removeLast() 删除尾元素,并把删除的尾元素返回 |
三、Set集合
1、Set集合特点: 无序, 不可重复
2、HashSet
(1) HashSet底层是HashMap
(2) 向hashSet集合中添加元素, 实际 上就是把这个元素作为键添加到了hashMap中
(3) hashset实际上是就是HashMap键的集合
(4) 因为HashMap中的键不允许重复, 所以hashset中不能存储重复的元素
3、TreeSet
TreeSet实现了SortedSet接口, SortedSet集合可以对元素进行自然排序, 所以TreeSet集合中的元素也会进行自然排序.
TreeSet集合存储的是引用类型数据, 要求TreeSet集合中的元素必须是可比较的
1)指定Comparator比较器
2)如果没有Comparator比较器, 元素的类需要实现Comparable接口
- TreeSet的特点:
-
1) 可以对元素进行自然排序
-
2) TreeSet底层是TreeMap
-
3) 向treeset集合中添加元素,实际上是把该元素作为键添加到了底层的treeMap中
-
4) TreeSet实际上就是TreeMap的键的集合
四、Map集合
1、java.util.Map集合结构图
2、常用方法
返回值 | 方法描述 |
---|---|
void | clear() 清空集合中所有的<键,值>对象 |
boolean | containsKey(Object key) 判断集合是否包含指定的键 |
boolean | containsValue(Object value) 判断集合是否包含指定的值 |
Set<Map.Entry<K,V>> | entrySet() 返回Entry的集合, 一个<键,值>对就是一个Entry |
boolean | equals(Object o) |
V | get(Object key) 返回指定的键对应的值 |
boolean | isEmpty() 判断Map是否为空 |
Set< K > | keySet() 返回所有的键的集合 |
V | put(K key, V value) 向集合中添加<key,value>键值对,如果键已存在, 使用新的value值替换原来的值 |
void | putAll(Map<? extends K,? extends V> m) 把m集合中的元素添加到当前集合中 |
V | remove(Object key) 移除key对应的<key,值>对 |
default boolean | remove(Object key, Object value) 移除<key, value>对 |
default V | replace(K key, V value) 使用value值替换key原来的值 |
default boolean | replace(K key, V oldValue, V newValue) |
int | size() 返回<键,值>对的数量 |
Collection< V > | values() 返回值的集合 |
3、HashMap
(1)HashMap的工作原理
(2)特点
-
- 底层是哈希表, 哈希表是一个数组, 数组的每个元素是一个单向链表,如果单向链表中结点的数量超过8,会把单向链表转换为树形结构
-
- HashMap底层数组的初始化容量: 16
-
- HashMap的加载因子默认大小: 0.75
当数组中元素的数量 > 数组长度*加载因子时, 数组要扩容
- HashMap的加载因子默认大小: 0.75
-
- HashMap底层数组的容量扩容时按 2 倍大小扩容
-
- 创建HashMap时, 如果指定初始化容量,系统会自动调整为2的幂次方, 就是为了快速计算数组的下标
-
- 理想状态下, 数组中的每个单向链表中结点的数量应该是平均分布的
系统是根据hash值计算索引值, 这个索引值应该是平均分布的
如果数组的长度是16, 可以把hash值对16求余 , 把余数作为数组的下标
i = (16 - 1) & hash 实际上就是把hash值的最后四位作为数组的下标
- 理想状态下, 数组中的每个单向链表中结点的数量应该是平均分布的
4、HashTable
-
- HashTable底层也是哈希表, HashTable是线程安全的, 使用了synchronized修饰了操作方法, HashMap不是线程安全的
-
- HashTable的父类是Dictionary,HashMap的父类是AbstractMap
-
- HashTable默认初始化容量: 11, HashMap初始化容量: 16
-
- HashTable默认加载因子: 0.75, 当hashtable中<键,值>对的数量 大于 数组的长度*加载因子时,进行扩容
-
- HashTable 默认扩容: 2倍 + 1 , HashMap默认扩容: 2倍
-
- HashTable也可以指定初始化容量, 不会调整; HashMap会把初始化容量调整为2的幂次方
-
- HashTable中的键或者值都不能为null, HashMap中的键与值可以为null
注意:也把哈希表的数组称为哈希桶