目录
(原创文章,转载请注明出处)
博主是计算机专业大学生,不定期更新原创优质文章,感兴趣的小伙伴可以关注博主主页支持一下,您的每一个点赞、收藏和关注都是对博主最大的支持!
一、概述
1.1 什么是集合框架?
Java集合框架是Java中用于存储和操作对象集合的一组接口和类的集合。Java集合框架提供了各种数据结构,如列表、集合、映射等,以及各种算法实现。
(1)常见的集合接口如下:
- List接口:表示一个有序的集合,允许包含重复元素,常见的实现类有ArrayList和LinkedList。
- Set接口:表示一个无序的集合,不允许包含重复元素,常见的实现类有HashSet和TreeSet。
- Queue接口:表示一个队列,用于存储待处理的任务,常见的实现类有LinkedList和PriorityQueue。
- Map接口:表示一个键值对的映射关系,常见的实现类有HashMap和TreeMap。
(2)常见的接口实现类如下:
- ArrayList:基于数组实现的集合,支持随机访问元素。
- LinkedList:双向链表实现的集合,支持快速插入和删除操作。
- HashSet:基于哈希表实现的集合,不允许重复元素。
- HashMap:基于哈希表实现的映射,键值对无序存储。
四大集合类的特点如下:
类 | 特点 |
---|---|
ArrayList | 有序、可重复、有索引 |
LinkedList | 有序、可重复、有索引 |
HashSet | 无序、不重复、无索引 |
HashMap | 无序、键不能重复、值可以重复、无索引 |
1.2 集合框架体系
(1)框架体系图
Java集合框架中类与类、类与接口的关系非常复杂,下面只展示部分关系:
(2)思维导图
由于类与接口的关系的复杂性,这里只重点介绍ArrayList类、LinkedList类、HashSet类和HashMap类的使用,接口与其实现类的思维导图如下:
二、ArrayList类
2.1 说明
(1)概述
ArrayList实现了List接口。它是一个基于数组的数据结构,提供了动态数组的功能,支持随机访问元素。
(2)特点
- 有序:元素按照插入的顺序存储。
- 可重复:可以存储重复的元素。
- 随机访问:可以通过索引快速访问任何位置的元素。
- 非线程安全:多个线程同时修改ArrayList时可能会导致数据不一致。
2.2 方法
以下是ArrayList类的部分方法,数据来源:Java中文文档-ArrayList类
方法 | 描述 |
---|---|
add(int index, E element) | 指定位置插入指定元素 |
add(E e) | 列表末尾插入指定元素 |
addAll(int index, Collection<? extends E> c) | 指定位置插入所有元素 |
addAll(Collection<? extends E> c) | 列表末尾插入所有元素 |
clear() | 删除所有元素 |
clone() | 复制并返回副本 |
contains(Object o) | 判断指定元素是否存在 |
forEach(Consumer<? super E> action) | 遍历元素并执行特定操作 |
get(int index) | 返回指定位置元素 |
isEmpty() | 判断列表是否为空 |
iterator() | 返回元素迭代器 |
remove(int index) | 删除指定位置的元素 |
remove(Object o) | 删除指定名称的元素 |
set(int index, E element) | 替换指定位置的元素 |
size() | 返回列表元素个数 |
下面是图片,方便移动端阅读
2.3 代码
(1)增删改查
import java.util.ArrayList;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
// 1.增加元素
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王五");
arrayList.add(3, "赵六");
System.out.println("添加元素之后:" + arrayList);
// 2.删除元素
arrayList.remove(3);
// 或者使用:arrayList.remove("赵六");
System.out.println("删除元素之后:" + arrayList);
// 3.更改元素
arrayList.set(2, "小王");
System.out.println("更改元素之后:" + arrayList);
// 4.查找元素
String index_1 = arrayList.get(1);
System.out.println("查找索引值为1的元素:" + index_1);
/*
* 输出:
* 添加元素之后:[张三, 李四, 王五, 赵六]
* 删除元素之后:[张三, 李四, 王五]
* 更改元素之后:[张三, 李四, 小王]
* 查找索引值为1的元素:李四
* */
}
}
(2)遍历元素
import java.util.ArrayList;
import java.util.Iterator;
public class TraversalArrayList {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王五");
// 法1:索引值for循环遍历
for (int i = 0; i < arrayList.size(); i++) {
System.out.println(arrayList.get(i));
}
// 法2:增强型for循环遍历
for (String s : arrayList) {
System.out.println(s);
}
// 法3:迭代器(Iterator)遍历
Iterator<String> iterator = arrayList.iterator();
while (iterator.hasNext()) { // 判断是否有元素
System.out.println(iterator.next()); // 获取元素、移动指针
}
// 法4:forEach()+Lambda表达式
arrayList.forEach(e -> System.out.println(e));
// arrayList.forEach(System.out::println);
}
}
三、LinkedList类
3.1 说明
(1)概述
LinkedList同样实现了List接口,但它基于双向链表数据结构,支持快速插入和删除操作。
(2)特点
- 有序:元素按照插入的顺序存储。
- 可重复:可以存储重复的元素。
- 顺序访问:访问元素时通常需要从头或尾开始遍历。
- 插入和删除效率高:在链表的开头或结尾插入或删除元素的时间复杂度为O(1)。
- 非线程安全:多个线程同时修改LinkedList时可能会导致数据不一致。
3.2 方法
以下是LinkedList类的部分方法, 数据来源:Java中文文档-LinkedList类
方法 | 描述 |
---|---|
add(int index, E element) | 指定位置插入指定元素 |
add(E e) | 列表末尾插入指定元素 |
addAll(int index, Collection<? extends E> c) | 指定位置插入所有集合元素 |
addAll(Collection<? extends E> c) | 列表末尾插入所有集合元素 |
addFirst(E e) | 列表开头插入元素 |
addLast(E e) | 列表末尾追加元素 |
clear() | 删除所有元素 |
clone() | 复制并返回副本 |
contains(Object o) | 判断指定元素是否存在 |
get(int index) | 返回指定位置元素 |
getFirst() | 返回第一个元素 |
getLast() | 返回最后一个元素 |
isEmpty() | 判断列表是否为空 |
iterator() | 返回元素迭代器 |
pop() | 出栈操作 |
push(E e) | 进栈操作 |
remove() | 删除头部元素 |
remove(int index) | 删除指定位置的元素 |
remove(Object o) | 删除指定名称的元素 |
set(int index, E element) | 替换指定位置的元素 |
size() | 返回列表元素个数 |
下面是图片,方便移动端阅读
3.3 代码
(1)增删改查
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
// 1.增加元素
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add(3, "赵六");
System.out.println("添加元素之后:" + linkedList);
// 2.删除元素
linkedList.remove(3);
System.out.println("删除元素之后:" + linkedList);
// 3.更改元素
linkedList.set(2, "小王");
System.out.println("更改元素之后:" + linkedList);
// 4.查找元素
System.out.println("头部元素:" + linkedList.getFirst());
System.out.println("尾部元素:" + linkedList.getLast());
System.out.println("查找索引值为1的元素:" + linkedList.get(1));
/*
* 输出:
* 添加元素之后:[张三, 李四, 王五, 赵六]
* 删除元素之后:[张三, 李四, 王五]
* 更改元素之后:[张三, 李四, 小王]
* 头部元素:张三
* 尾部元素:小王
* 查找索引值为1的元素:李四
* */
}
}
(2)遍历元素
import java.util.Iterator;
import java.util.LinkedList;
public class TraversalLinkedList {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
// 法1:索引值for循环遍历
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
// 法2:增强型for循环遍历
for (String s : linkedList) {
System.out.println(s);
}
// 法3:迭代器(Iterator)遍历
Iterator<String> iterator = linkedList.iterator();
while (iterator.hasNext()) { // 判断是否有元素
System.out.println(iterator.next()); // 获取元素、移动指针
}
// 法4:forEach()+Lambda表达式
linkedList.forEach(e -> System.out.println(e));
// linkedList.forEach(System.out::println);
}
}
四、HashSet类
4.1 说明
(1)概述
HashSet实现了Set接口,它基于HashMap实现,但不包含键值对。它存储的元素是唯一的,不允许重复。
(2)特点
- 无序:元素存储的顺序与插入的顺序可能不同。
- 不可重复:每个元素最多只能出现一次。
- 非线程安全:多个线程同时修改HashSet时可能会导致数据不一致。
4.2 方法
以下是HashSet类的部分方法, 数据来源:Java中文文档-HashSet类
方法 | 描述 |
---|---|
add(E e) | 添加指定元素 |
addAll(Collection<? extends E> c) | 添加所有元素 |
clear() | 删除所有元素 |
clone() | 复制并返回副本 |
contains(Object o) | 判断指定元素是否存在 |
isEmpty() | 判断集合是否为空 |
iterator() | 返回元素迭代器 |
remove(Object o) | 删除指定名称的元素 |
size() | 返回集合元素个数 |
下面是图片,方便移动端阅读
4.3 代码
(1)增删查改
import java.util.HashSet;
public class HashSetTest {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
// 1.增加元素
hashSet.add("张三");
hashSet.add("李四");
hashSet.add("王五");
hashSet.add("赵六");
System.out.println("添加元素之后:" + hashSet);
// 2.删除元素
hashSet.remove("赵六");
System.out.println("删除元素之后:" + hashSet);
// 3.更改元素
/*
* HashSet 不支持直接更改元素,因为 Set 中的元素是不可变的。
* 如果需要更改元素,需要先删除旧元素,然后添加新元素。
* 这是因为 Set 中的元素是不可变的,每个元素都有一个唯一的哈希码,
* 这个哈希码在元素被添加到 Set 时就确定了,不能更改
* */
hashSet.remove("王五");
hashSet.add("小王");
System.out.println("更改元素之后:" + hashSet);
// 4.查找元素
System.out.println("李四是否存在:" + hashSet.contains("李四"));
/*
* 输出:
* 添加元素之后:[李四, 张三, 王五, 赵六]
* 删除元素之后:[李四, 张三, 王五]
* 更改元素之后:[李四, 张三, 小王]
* 李四是否存在:true
* */
}
}
(2)遍历元素
import java.util.HashSet;
import java.util.Iterator;
public class TraversalHashSet {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("张三");
hashSet.add("李四");
hashSet.add("王五");
// 法1:增强型for循环遍历
for (String s : hashSet) {
System.out.println(s);
}
// 法2:迭代器(Iterator)遍历
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) { // 判断是否有元素
System.out.println(iterator.next()); // 获取元素、移动指针
}
// 法3:forEach()+Lambda表达式
hashSet.forEach(e -> System.out.println(e));
// hashSet.forEach(System.out::println);
}
}
五、HashMap类
5.1 说明
(1)概述
HashMap实现了Map接口,它存储键值对,并允许使用null作为键或值(但只能有一个null键)。
(2)特点
- 无序:键值对的存储顺序与插入的顺序可能不同。
- 键唯一:每个键最多只能对应一个值,但值可以重复。
- 非线程安全:多个线程同时修改 HashMap 时可能会导致数据不一致。
- 高效查找:基于哈希表实现,查找、插入和删除操作的时间复杂度通常为O(1)。
5.2 方法
以下是HashMap类的部分方法,数据来源 :Java中文文档-HashMap类
方法 | 描述 |
---|---|
clear() | 删除映射所有键值对 |
clone() | 复制并返回副本 |
containsKey(Object key) | 判断指定键的键值对是否存在 |
containsValue(Object value) | 判断指定值的键值对是否存在 |
entrySet() | 返回映射对应的集合 |
get(Object key) | 返回指定键的键值对的值 |
isEmpty() | 判断映射是否为空 |
keySet() | 返回映射的所有键的集合 |
put(K key, V value) | 映射中添加键值对 |
putAll(Map<? extends K,? extends V> m) | 映射中添加另一映射所有键值对 |
remove(Object key) | 删除指定键的键值对 |
remove(Object key, Object value) | 删除指定键值对 |
size() | 返回映射键值对个数 |
values() | 返回映射的所有值的集合 |
下面是图片,方便移动端阅读
5.3 代码
(1)增删查改
import java.util.HashMap;
public class HashMapTest {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
// 1.增加元素
hashMap.put(101, "张三");
hashMap.put(102, "李四");
hashMap.put(103, "王五");
hashMap.put(104, "赵六");
System.out.println("增加元素之后:" + hashMap);
// 2.删除元素
// 2.1 删除指定元素
hashMap.remove(104);
// hashMap.remove(104, "赵六");
System.out.println("删除元素之后:" + hashMap);
// 2.2 删除全部元素
// hashMap.clear();
// 3.更改元素
hashMap.replace(103, "小王");
// hashMap.replace(103,"王五","小王");
System.out.println(hashMap);
// 4.查找元素
System.out.println("查找键为102的元素:" + hashMap.get(102));
/*
* 输出:
* 增加元素之后:{101=张三, 102=李四, 103=王五, 104=赵六}
* 删除元素之后:{101=张三, 102=李四, 103=王五}
* {101=张三, 102=李四, 103=小王}
* 查找键为102的元素:李四
* */
}
}
(2)遍历元素
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class TraversalHashMap {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(101, "张三");
hashMap.put(102, "李四");
hashMap.put(103, "王五");
// 法1:增加型for循环 + keySet()和get()方法
for (Integer key : hashMap.keySet()) {
System.out.println(key + "=" + hashMap.get(key));
}
// 法2:增加型for循环 + entrySet()方法
for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
// 注:Map.Entry是Map的一个内部接口
System.out.println(entry.getKey() + "=" + entry.getValue());
}
// 法3:迭代器(Iterator) + entrySet()方法
Iterator<Map.Entry<Integer, String>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) { // 判断是否有元素(键值对)
System.out.println(iterator.next()); // 获取元素(键值对)、移动指针
}
// 法4:forEach()方法 + Lambda表达式
hashMap.forEach((key, value) -> System.out.println(key + "=" + value));
}
}
六、Collections类
6.1 说明
Collections类是Java中的一个非常有用的工具类,这个类在java.util包中,它提供了许多静态方法来操作或处理集合(如列表、集合、映射等),注意和Collection接口区分。
6.2 方法
Collections类的方法为静态方法,可直接调用,数据来源:Java中文文档-Collections类
方法 | 描述 |
---|---|
addAll() | 添加指定元素 |
replaceAll() | 替换指定元素 |
sort() | List集合元素排序 |
reverse() | List集合元素反转 |
shuffle() | 打乱List集合元素顺序 |
binarySearch() | 二分查找指定元素的索引 |
max() | 返回集合中的最大元素 |
min() | 返回集合中的最小元素 |
frequency() | 返回指定元素在集合中出现的次数 |
emptySet() | 返回一个空的Set集合 |
emptyList() | 返回一个空的List集合 |
emptyMap() | 返回一个空的Map集合 |
singleton() | 返回只包含指定元素的单元素Set集合 |
6.3 代码
(1)增删改查
import java.util.ArrayList;
import java.util.Collections;
public class CollectionsTest1 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
// 1.增加元素
Collections.addAll(arrayList, "张三", "李四", "王五");
System.out.println("添加元素之后:" + arrayList);
// 2.删除元素
/* Collections类没有提供删除集合元素的方法 */
// 3.更改元素
Collections.replaceAll(arrayList, "王五", "小王");
System.out.println("更改元素之后:" + arrayList);
// 4.查找元素(二分法查找)
int index = Collections.binarySearch(arrayList, "张三");
System.out.println("张三的索引值:" + index);
/*
* 输出:
* 添加元素之后:[张三, 李四, 王五]
* 更改元素之后:[张三, 李四, 小王]
* 张三的索引值:0
* */
}
}
(2)其他操作
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
public class CollectionsTest2 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("100");
arrayList.add("abc");
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王五");
// 1.排序
Collections.sort(arrayList); //默认按ASCII/Unicode码排序
System.out.println("集合元素排序:" + arrayList);
// 2.反转
Collections.reverse(arrayList);
System.out.println("反转元素顺序:" + arrayList);
// 3.复制
LinkedList<String> linkedList = new LinkedList<>(Arrays.asList(new String[arrayList.size()]));
/* 动态初始化一个长为arrayList.size()的数组,使用asList()方法转化为List集合 */
// System.out.println("初始化LinkedList:" + linkedList);
Collections.copy(linkedList, arrayList);
System.out.println("复制元素到LinkedList:" + linkedList);
// 4.最大值
String max = Collections.max(arrayList);
System.out.println("最大值:" + max);
// 5.最小值
String min = Collections.min(arrayList);
System.out.println("最大值:" + min);
// 6.统计元素出现次数
int frequency = Collections.frequency(arrayList, "张三");
System.out.println("张三出现次数:" + frequency);
/*
* 输出:
* 集合元素排序:[100, abc, 张三, 李四, 王五]
* 反转元素顺序:[王五, 李四, 张三, abc, 100]
* 复制元素到LinkedList:[王五, 李四, 张三, abc, 100]
* 最大值:王五
* 最大值:100
* 张三出现次数:1
* */
}
}
若有不妥之处,恳请读者批评指正