集合
单列集合
单列集合Collection
是所有单列集合实现接口及类的父类,其下有List
和Set
两个接口,而List
下又有ArrayList
、LinkedList
和Vector
(已淘汰)三个实现类,Set
下有HashSet
和TreeSet
两个实现类,HashSet
又是LinkedHashSet
的父类。。。
Collection
中常用的方法有如下
add(E)
,添加一个元素到集合中
1 | Collection<String> col1 = new ArrayList<>(); |
addAll(Collection)
,添加另一集合中的所有元素到当前集合中
1 | Collection<String> col1 = new ArrayList<>(); |
remove(E)
,移除一个元素
1 | Collection<String> col1 = new ArrayList<>(); |
removeAll(Collection)
,移除与另一集合的序列相似的序列
1 | Collection<String> col1 = new ArrayList<>(); |
retainAll(Collection)
,求两集合的并集
1 | Collection<String> col1 = new ArrayList<>(); |
removeIf(Predicate)
,条件移除,匿名类Predicate
的test
方法返回true
时元素被移除
1 | Collection<String> col1 = new ArrayList<>(); |
clear()
,清空元素
isEmpty()
,集合是否为空
size()
,集合大小
contains(E)
,集合中是否包含某一元素
containsAll(Collection)
,集合中是否包含另一集合的序列
iterator()
,迭代器
1 | // 获取迭代器 |
List
List
中的元素有序、可重复、有索引
List
集合除包含Collection
的所有方法之外,还有如下方法
add(int, E)
,在集合的指定位置添加元素
1 | List<String> list1 = new ArrayList<>(); |
remove(int)
,移除指定位置的元素
1 | // 移除下标为0的元素 |
get(int)
,获取指定位置的元素
set(int, E)
,修改指定位置的元素
Set
Set
中的元素无序、不重复、无索引
HashSet
HashSet
的底层是一个默认长度为16
的数组,存储时根据元素的哈希值和数组的长度计算出元素在哈希表中的位置,如果当前位置为空,则直接存入,不为空则采用拉链法储存,通过equals
与链表中元素的内容依次对比,确保不重复,若不重复,将新元素挂在老元素的下面(JDK8及以后);当拉链法链表的长度大于8
且数组长度大于等于64
时,链表会自动转换成红黑树,以提高查找效率
HashSet
中的元素无序、不重复、无索引,如果集合中存储的对象是自定义对象,则必须重写hashCode()
和equals(Object)
方法,如下TestBean
类中
如果不重写hashCode()
,那么底层将会通过地址值生成对象的哈希值;如果不重写equals(Object)
,那么底层将对通过地址值对两个对象进行比较,为了确保Set
集合中的不重复性,必须重写这两个方法
1 | public class TeatBean { |
LinkedHashSet
LinkedHashSet
是HashSet
的子类,但是它的元素是有序的,其底层数据结构依然是哈希表,不过元素之间通过双链表记录存储顺序
TreeSet
TreeSet
的底层基于红黑树实现,元素可排序、不重复、无索引
TreeSet
在遍历时似乎是使用二叉树的先序遍历方式
对于数值类型数据,TreeSet
默认会按照从小到大的顺序排列
对于字符或字符串类型数据,TreeSet
默认按照字符在ASCII
码表中的数字升序排序;经测试,如果字符串是中文,将按照Unicode
编码中的数值部分升序排序,如下代码,将输出[哥, 帅, 我, 是]
1 | char 我 = '\u6211'; |
对于自定义对象,必须添加对象比较规则,可采用如下两种方式
- 第一种:实现
Comparable<E>
接口,重写compareTos(E e)
方法
TreeSet
底层是由红黑树实现,插入结点时也按照红黑树的插入规则;compareTos(E e)
方法中的参数表示红黑树中已被插入的结点,当前对象this
代表等待插入的结点;插入时通过compareTos(E e)
依次比较新结点与已有结点,得出新结点的插入位置
compareTos(E e)
的返回值类型为int
,当返回值小于0
时,代表插入已有结点的左侧,当返回值大于0
时,代表插入已有结点的右侧,当返回值等于0
时,代表插入当前位置
1 | public class TestBean implements Comparable<TestBean> { |
- 第二种:创建
TreeSet
集合时,传入Comparator<E>
对象,重写compare(E e1, E e2)
方法,其中e1
代表红黑树中已被插入的结点,e2
代表等待插入的结点;插入时通过compare(E e1, E e2)
依次比较新结点与已有结点,得出新结点的插入位置
compare(E e1, E e2)
的返回值类型为int
,当返回值小于0
时,代表插入已有结点的左侧,当返回值大于0
时,代表插入已有结点的右侧,当返回值等于0
时,代表插入当前位置
1 | TreeSet<TestBean> treeSet = new TreeSet<>(new Comparator<TestBean>() { |
双列集合
双列集合Map
是所有双列集合实现接口及类的父类,其下有HashMap
和TreeMap
两个实现类,HashMap
下又有LinkedHashMap
子类
Map
中常用的方法如下
put(K key, V value)
,添加键值和元素到集合中
1 | Map<String, TestBean> map = new HashMap<>(); |
get(K key)
,根据键值获取指定的元素
1 | Map<String, TestBean> map = new HashMap<>(); |
remove(Object obj)
,根据键值删除指定的元素
1 | Map<String, TestBean> map = new HashMap<>(); |
clear()
,清空集合中所有键值对
containsKey(Object obj)
,集合中是否包含某个键
containValue(Object obj)
,集合中是否包含某个值
isEmpty()
,集合是否为空
size()
,集合中键值对的个数
keySet()
,把Map
集合中的所有键放到一个Set
集合中
1 | Map<String, TestBean> map = new HashMap<>(); |
entrySet()
,把Map
集合中的所有键值对放到一个Set
集合中
1 | Map<String, TestBean> map = new HashMap<>(); |
HashMap
HashMap
和HashSet
的底层一样,都是一个默认长度为16的数组,区别是在put
时如果键相同,新的值会覆盖旧的值
如果key
是自定义对象,则必须重写hashCode()
和equals(Object)
方法
1 | public class MyKey { |
1 | Map<MyKey, TestBean> map = new HashMap<>(); |
LinkedHashMap
LinkedHashMap
是HashMap
的子类,但是它的键值对是有序的,其底层数据结构依然是哈希表,不过键值对之间通过双链表记录存储顺序
TreeMap
对于数值类型数据,TreeMap
默认会按照从小到大的顺序排列
TreeMap
的底层基于红黑树实现,对于自定义对象的Key
,可以根据Key
进行排序,与TreeSet
类似,有如下两种排序方式
第一种:实现
Comparable<E>
接口,重写compareTos(E e)
方法第二种:创建
TreeMap
集合时,传入Comparator<E>
对象,重写compare(E e1, E e2)
方法