220805-集合
集合
概述
集合主要分为单列集合、双列集合
Collection接口有两个重要的子接口List、Set,他们实现子类都是单列集合
Map接口的实现子类是双列集合,K-V
List:是一个有序集合,可以放重复的数据,有索引
- ArrayList、LinkedList:有序、可重复、有索引
Set:是一个无序集合,不允许放重复的数据,无索引
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- TreeSet:按照大小默认升序排序、不重复、无索引
Map:是一个无序集合,集合中包含一个键对象,一个值对象,键对象不允许重复,值对象可以重复(身份证号—姓名)
数组与集合
数组:
- 长度开始时必须指定,而且一旦指定,不能改变
- 保存的必须为同一类型的元素
- 使用数组进行增加元素的代码麻烦
集合:
- 可以动态保存任意多个对象,使用比较方便
- 提供了一系列方便的操作对象的方法:add,remove,set,get
- 使用集合添加、删除新元素,代码简洁
- 集合和泛型都只支持引用数据类型,不支持基本数据类型,所以集合中存储的元素都是对象
Collection集合
- collection实现子类可以存放多个元素,每个元素可以是Object
- 有些Collection的实现类,可以存放重复的元素,有些不可以
- Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的
Collection的常用方法
返回值 | 方法 | 含义 |
---|---|---|
boolean | add | 添加单个元素 |
boolean | addAll | 添加多个元素 |
viod | clear | 清空 |
boolean | contains | 查找元素是否存在 |
boolean | containsAll | 查找多个元素是否都存在 |
boolean | equals | 比较此 collection 与指定对象是否相等。 |
boolean | isEmpty | 判断是否为空 |
boolean | remove | 删除指定元素 |
boolean | removeAll | 删除多个元素 |
Collection 接口遍历元素方式 1-使用 Iterator(迭代器)
Iterator对象称为迭代器,主要用于编列Collection集合中的元素
1 | //得到当前集合的迭代器对象 |
- 迭代器的默认位置:索引0
- 越界会出现NoSuchElementException异常
Collection 接口遍历对象方式 2-for 循环增强
- 内部原理是一个Iterator迭代器,遍历集合相当于迭代器的简化写法
- 增强for循环:既可以遍历集合也可以遍历数组
- 实现Iterable接口的类才可以使用迭代器和增强for,Collection接口已经实现了Iterable接口
1 | Collection<String> list = new ArrayList<>(); |
- 增强for不会改变原集合或数组中的值,修改无意义
Lambda表达式遍历集合
1 | //forEach常规写法 |
List集合
List 接口下面主要有两个实现 ArrayList 和 LinkedList,他们都是有顺序的,也就是放进去
是什么顺序,取出来还是什么顺序,也就是基于线性存储,可以看作是一个可变数组
- ArrayList:查询数据比较快,添加和删除数据比较慢(基于可变数组)
- LinkedList:查询数据比较慢,添加和删除数据比较快(基于链表数据结构)
- Vector:Vector 已经不建议使用,Vector 中的方法都是同步的,效率慢,已经被 ArrayList取代
- Stack 是继承 Vector 实现了一个栈,栈结构是后进先出,目前已经被 LinkedList 取代
开发中,一般情况下,使用多态创建集合
List<Integer> l1 = new ArrayList<>();
初始化集合尽量指定初始化容量,默认指定为16
List的四种种遍历方式[ArrayList、LinkedList、Vector]
方式一:使用Iterator
1 | Iterator iter = col.iterator(); |
方式二:使用增强for
1 | for(Object o : col){ |
方式三:使用普通for
1 | for(int i = 0;i<list.size();i++){ |
方式四:Lambda表达式
1 | lists.forEach(s -> { |
遍历存在的问题
- 迭代器遍历集合且直接用集合删除元素可能出现
- 增强for遍历集合且直接用集合删除元素可能出现
解决方案
- 用迭代器自身的remove去删除元素
- 使用普通for循环采取i– 或倒序删除
- 不能使用增强for循环删除集合中元素
ArrayList
- ArrayList是由数组来实现数据存储的
- ArrayList基本等同于Vector,除了ArrayList是线程不安全的(执行效率高),在多线程情况下,不建议使用ArrayList
- 可以加入多个null
方法 | 描述 |
---|---|
add() | 将元素插入到指定位置的 arraylist 中 |
addAll() | 添加集合中的所有元素到 arraylist 中 |
clear() | 删除 arraylist 中的所有元素 |
clone() | 复制一份 arraylist |
contains() | 判断元素是否在 arraylist |
get() | 通过索引值获取 arraylist 中的元素 |
indexOf() | 返回 arraylist 中元素的索引值 |
removeAll() | 删除存在于指定集合中的 arraylist 里的所有元素 |
remove() | 删除 arraylist 里的单个元素 |
size() | 返回 arraylist 里元素数量 |
isEmpty() | 判断 arraylist 是否为空 |
subList() | 截取部分 arraylist 的元素 |
set() | 替换 arraylist 中指定索引的元素 |
sort() | 对 arraylist 元素进行排序 |
toArray() | 将 arraylist 转换为数组 |
toString() | 将 arraylist 转换为字符串 |
ensureCapacity() | 设置指定容量大小的 arraylist |
lastIndexOf() | 返回指定元素在 arraylist 中最后一次出现的位置 |
retainAll() | 保留 arraylist 中在指定集合中也存在的那些元素 |
containsAll() | 查看 arraylist 是否包含指定集合中的所有元素 |
trimToSize() | 将 arraylist 中的容量调整为数组中的元素个数 |
removeRange() | 删除 arraylist 中指定索引之间存在的元素 |
replaceAll() | 将给定的操作内容替换掉数组中每一个元素 |
removeIf() | 删除所有满足特定条件的 arraylist 元素 |
forEach() | 遍历 arraylist 中每一个元素并执行特定操作 |
ArrayList集合底层原理
- ArrayList底层是基于数组实现的:根据索引定位元素块,增删需要做元素的移位操作
- 当创建ArrayList对象时,如果使用的时无参构造器,则初始容量为0;第一次添加,则扩容至10,如需要再次扩容,则扩容1.5倍
- 如果使用的时指定大小的构造器,则初始为指定的大小,如需扩容,直接扩容当前的1.5倍
ArrayList查询快,增删慢
Vector
- Vector底层也是一个对象数组
- Vector是线程同步的,即线程安全。Vector类的操作方法带有synchronized
- 在开发中,需要线程同步安全,考虑Vector
ArrayList与Vector比较
ArrayList:可变数组;不安全,效率高;如果有参构造1.5倍;如果无参:第一次10、第二次1.5倍扩
Vector:可变数组;安全效率不高;如果无参,默认是10;之后2倍扩容
LinkedList
- LinkedList实现了双向链表和双端队列特点
- 可以添加任意元素(元素可重复),包括null
- 线程不安全,没有实现同步
LinkedList特有功能
方法名称 | 说明 |
---|---|
addFirst(E e) | 在该列开头添加指定元素 |
addLast(E e) | 将指定的元素追加到此列表的末尾 |
getFirst() | 返回此列表中的第一个元素 |
getLast() | 返回此列表中的最后一个元素 |
removeFirst() | 删除并返回第一个元素 |
removeLast() | 删除并返回最后一个元素 |
LinkedList底层原理
- 底层数据结构是双链表、查询慢、首尾操作的速度极快
- LinkedList中维护两个属性first和last分别指向首节点和尾节点
ArrayList和LinkedList
底层结构 | 增删的效率 | 改查的效率 | |
---|---|---|---|
ArrayList | 可变数组 | 较低、数组扩容 | 较高 |
LinkedList | 双向链表 | 较高、链表追加 | 较低 |
Set接口
- 无序(添加与取出的顺序不一致,没有索引
- 不允许添加重复元素,最多只有一个null
注:
- 不能使用索引来获取对象
- 虽然是随机添加顺序,但取出的是固定的顺序
HashSet
- HashSet实现了Set接口
- HashSet实际上是HashMap
- 可以存放null值,但是只能有一个null
- HashSet不保证元素是有序的
- 不能有重复元素
HashSet底层机制
HashSet底层是HashMap,HashMap底层是(数组+链表+红黑树)
LinkedHashSet
- LinkedHashSet是HashSet的子类
- LinkedHashSet底层是LinkedHashMap,底层维护了一个数组+双向链表
- LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
- LinkedHashSet不允许添加重复元素
LinkedHashSet底层机制
- LinkedHashSet维护了一个hash表和双向链表
Map接口*
- Map和Collection并列存在。
- Map中的key和value可以是任何引用类型的数据
- Map中的key不可以重复;value可以重复
- Map中的key和value可以为null;但key中只能有一个null
- 常用String类作为Map中的key
- key与value是一对一的关系
常用方法
方法 | 描述 |
---|---|
clear() | 删除 hashMap 中的所有键/值对 |
clone() | 复制一份 hashMap |
isEmpty() | 判断 hashMap 是否为空 |
size() | 计算 hashMap 中键/值对的数量 |
put() | 将键/值对添加到 hashMap 中 |
putAll() | 将所有键/值对添加到 hashMap 中 |
putIfAbsent() | 如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。 |
remove() | 删除 hashMap 中指定键 key 的映射关系 |
containsKey() | 检查 hashMap 中是否存在指定的 key 对应的映射关系。 |
containsValue() | 检查 hashMap 中是否存在指定的 value 对应的映射关系。 |
replace() | 替换 hashMap 中是指定的 key 对应的 value。 |
replaceAll() | 将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。 |
get() | 获取指定 key 对应对 value |
getOrDefault() | 获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值 |
forEach() | 对 hashMap 中的每个映射执行指定的操作。 |
entrySet() | 返回 hashMap 中所有映射项的集合集合视图。 |
keySet() | 返回 hashMap 中所有 key 组成的集合视图。 |
values() | 返回 hashMap 中存在的所有 value 值。 |
merge() | 添加键值对到 hashMap 中 |
compute() | 对 hashMap 中指定 key 的值进行重新计算 |
computeIfAbsent() | 对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中 |
computeIfPresent() | 对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。 |
1 | public class MapMethod { |
HashMap小结
- Map接口的常用实现类:HashMap、Hashtable、Properties
- HashMap是Map接口中使用频率最高的实现类
- HasMap是以key-val对的方式存储数据
- key不能重复,但是值可以重复,允许使用null键和null值
- 如果添加相同的key,则会覆盖原来的key-val,等同于修改
- 和HashSet一样,不保证映射的顺序,因为底层是以hash表的方式存储的
- HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作
Hashtable的基本介绍
- 存放键值对K-V
- Hashtable的键值都不能为null,否则会抛异常
- Hashtable使用的方法基本和HashMap方法一样
- Hashtable是线程安全的,HashMap是线程不安全的
- 与HashMap比效率较低
TreeSet
Collections工具类
Collections是一个操作Set、List、Map等集合的工具类
排序操作
方法 | 含义 |
---|---|
reverse(List) | 反转List中元素的顺序 |
shuffle(List) | 对List集合元素进行随机排序 |
sort(List) | 对List升序排序 |
sort(List,Comparator) | 根据指定的Comparator产生的顺序对List集合元素进行排序 |
swap(List,int,int) | 将指定List集合中的i处元素和j处元素进行交换 |
1 |
|
删除、查找
方法 | 含义 |
---|---|
Object max | 返回最大元素 |
Object max | |
Object min | |
Object min | |
int frequency | |
void copy | |
boolean replaceAll |
1 |
|
本篇文章参考:
韩顺平Java基础
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment