集合
集合
此系列笔记来源于
BiliBili韩顺平老师的Java基础课
介绍
1、集合主要分为单列集合和双列集合
2、Collection 接口有两个重要的子接口 List 和 Set,他们的实现子类都是单列集合
3、Map 接口的实现子类是双列集合,存放Key-Value
集合体系图
Collection
Collection接口常用方法(ArrayList为例)
1、add(…):添加单个元素
2、remove(…):删除指定元素
3、contains(…):查找元素是否存在
4、size():获取元素个数
5、isEmpty():判断是否为空
6、clear():清空元素
7、addAll(…):添加多个元素
8、containsAll():查找多个元素是否都存在
9、removeAll():删除多个元素
Iterator接口的方法
1、Iterator iterator = xxx.iterator(); 得到集合的迭代器
2、hasNext():返回是否存在下一个迭代器
3、next():iterator变为下一个迭代器,也可以将下一个集合位置上的元素返回
4、remove():删除元素
PS:
(1)next()方法调用前必须要先用hasNext()进行检测,若无下一个集合元素,调用则会抛出NoSuchElementException异常
(2)遍历完后迭代器指向最后一个元素,如果要重新遍历需要重置迭代器
Iterator iterator = col.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next(); //用Object类接受
...
}
快捷键:itit
显示所有快捷键:ctrl + j
for循环增强
底层是迭代器
for (数据类型 变量名 : 遍历集合) {
}
//细分两个子接口
List
1、List集合类中的元素有序(添加顺序与取出顺序一致),且可重复
2、支持索引 xx.get(3) //取出第四个元素,下标从0开始
3、List下有很多实现类
常用方法:
1、void add(int index, Object ele):在index位置插入ele元素,无indext则在最后插入
2、boolean addAll(int index, Collection eles):index位置将eles中所有元素加入
3、Object get(int index):获取index位置的元素
4、int indexOf(Object obj):返回obj在集合中首次出现的位置
5、int lastIndexOf(Object obj):返回obj在集合中末次出现的位置
6、Object remove(int index):移除index未知的元素,并返回该元素
7、Object set(int index, Object ele):设置index位置的元素为ele
8、List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
ArrayList
注意事项
1、支持所有元素,包括null
2、ArrayList 是线程不安全的 (源码无synchronized)
3、ArrayList是由数组实现的
4、ArrayList 基本等同于 Vector,除了ArrayList 线程不安全(运行效率高)
底层结构与源码分析
结论:
Vector
注意事项
1、Vector底层也是是对象数组 protected Object[] elementData;
2、Vector 是线程同步的,即线程安全,其操作方法带有synchronized
Vector 和 ArrayList的比较
LinkedList
说明
1、LinkedList底层实现了双向链表和双端队列特点
2、可以添加任意元素(可以重复),包括null
3、线程不安全
LinkedList的底层操作机制
Set
Set接口基本介绍
1、无序(添加和取出的顺序不一致),无索引
2、不允许重复元素,最多包含一个null
常用方法
Set接口也是Collection的子接口,因此常用方法和Collection接口一样
遍历方式
同Collection的遍历方式一样
1、可以使用迭代器
2、可以使用增强for
3、不能使用索引的方式来获取
HashSet
说明
1、HashSet实现了Set接口
2、HashSet实际上是HashMap,HashMap的底层是 数组 + 链表 + 红黑树
PS:
1、add():添加一个对象,同时返回一个boolean值,添加成功则返回true,否则返回false
2、
HashSet set = newHashSet();
set.add(new Book("1"));
set.add(new Book("1"));
上面两个是都可以添加成功的,因为是不同对象,内存指向堆
set.add(1);
set.add(1);
上面第二个无法添加成功,因为已经添加了1,内存指向常量池
set.add(new String("123"));
set.add(new String("123"));
两个都可以添加成功
HashSet底层添加元素
重写equals在类里面,alt + insert
LinkedHashSet
说明
1、LinkedHashSet 是 HashSet的子类
2、LinkedHashSet 底层是一个 LinkedHashMap,底层维护了一个 数组 + 双向链表
3、LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,同时使用链表维护元素的次序,这是的元素看起来是以插入顺序保存的
4、LinkedHashSet 不允许添加重复元素
底层结构与源码分析
1、第一次添加元素后,数组table直接扩容到16,数组是HashMapEntry
Map(JDK8)
1、 Map 与 Collection 并列存在,用于保存具有映射关系的数据:Key - Value(双列元素)
2、Map 中的 Key 和 Value 可以是任何引用类型的数据,会封装到 HashMap$Node 对象中
3、Key 不允许重复,原因和 HashSet 一样,Value 可以重复
4、Map 中的 Key 和 Value 都可以为 null ,但 Key 只能有一个 null
5、Key 和 Value 一对一,通过 Key 可以找到 Value
xx.get(Key);
6、一对 K - V 是放在一个 HashMap$Node 中的, Node 实现了 Entry接口,有些书上也说 一对 K - V 就是一个 Entry,为了方便遍历,还会创建 entrySet 集合,存放 Entry
7、entrySet中,定义的类型是 Map.Entry,但实际上存放的、运行类型还是 HashMap$Node,因为 static class Node<K, V> implements Map.Entry<K, V>
entrySet类似于一个大表,方便遍历,Entry接口提供了 getvalue(), getKey()方法(需要向下转型成Map.Entry才能使用)
8、HashMap 还提供了 keySet、Values……
9、HashMap 没有实现同步,线程不安全
10、jdk8的 HashMap 底层是 数组 + 链表 + 红黑树
Map接口常用方法
1、remove:根据 Key 删除映射关系
2、get:根据 Key 获取值
3、size:获取元素个数
4、isEmpty:判断个数是否为0
5、clear:清除
6、containsKey:查找键是否存在
Map遍历方式
Map map = new HashMap();
map.put(...);
...
//一、先取出所有的 Key,通过 Key 取出对应的 Value
Set keyset = map.keySet();
//(1)增强for
for (Object key : keyset) {
}
//(2)迭代器
Iterator iterator = keyset.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
}
//二、把所有values取出
Collection values = map.values();
... //同一
//三、通过EntrySet来获取K-V
//(1)增强for
for (Object entry : entrySet) {
Map.Entry m = (Map.Entry)entry;
m.getKey() m.getValue()...;
}
//(2)迭代器
Iterator iterator entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry m = (Map.Entry)iterator.next(); //iterator的运行类型是HashMap$Node,需要向下转型成Map.Entry,之后才能用getKey、getValue
m.getKey() m.getValue()...;
//要获取Value的对象还需要向下转型一次
(XXX)xxx = (XXX)m.getValue();
}
HashMap扩容机制(和HashSet相同)
Hashtable
1、存放的元素值键值对 K - V
2、K - V 均不能为 null,否侧会抛出 NullPointerException
3、Hashtable 线程安全,HashMap 不安全
Hashtable扩容机制
1、数组 Hashtable$Entry[] 初始化大小为11
2、临界值threshold 8(11 * 0.75)
3、每次扩容一倍加一 int new Capacity = (oldCapacity << 1) + 1;
Properties
1、Properties类继承自 Hashtable类并且实现了 Map接口,保存键值对 K - V
2、使用特点与 Hashtable类似,K - V 不能用null
3、Properties 还可以用于从 xxx.properties 文件中,加载数据到 Properties类对象,并进行读取和修改
4、工作后,xxx.properties文件常常作为配置文件
TreeSet
1、当使用无参构造器创建 TreeSet时,仍然是无序的
2、可以传入比较器(匿名内部类)来进行不同顺序的排序
3、add方法传入的对象需要有实现Comparator接口,否则会抛出ClassCastException异常
//按字符串从小到大排序
TreeSet treeSet = new TreeSet(new Comparator() {
public int compare(Object o1, Object o2) {
return ((String)o1).compareTo((String)o2);
}
})
可以通过修改compare函数,如果返回的值为0,那么就不加入此元素,不是替换
TreeMap
1、当使用无参构造器创建 TreeMap 时,仍然是无序的
2、可以传入比较器(匿名内部类)来进行不同顺序的排序
//按字符串从小到大排序
TreeMap treeMap = new TreeMap(new Comparator() {
public int compare(Object o1, Object o2) {
return ((String)o1).compareTo((String)o2);
}
})
可以通过修改compare函数,如果返回的值为0,那么就不加入此元素,不是替换
Collections工具类
介绍
1、Collections是一个操作 Set、List 和 Map 等集合的工具类
2、Collections 中提供了一系列静态方法对劲和元素进行排序、查询和修改等操作
排序操作
1、reverse(x):对集合x元素进行反转
2、shuffle(x):对集合x元素进行随机排序
3、sort(x):按照元素的自然顺序对集合x进行升序排序
4、sort(x, Comparator):根据指定的 Comparator 产生的顺序对集合x的元素进行排序
5、swap(x, int, int):将集合x中的两处元素进行交换
查找、替换
PS:1、copy的时候需要保证第二个参数集合的长度小于等于第一个
一道很有意思的题目:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器