蓝桥杯JavaB组之集合框架(ArrayList、HashMap 基础操作)
一、Java 集合框架简介
Java 集合框架(Collection Framework) 是 存储和操作数据的强大工具,用于处理 动态数据、去重、映射、排序等操作。蓝桥杯中,高频考点 包括: ✅ ArrayList:动态数组,适合存储有序数据
✅ HashSet:无序集合,适合去重
✅ HashMap:键值对存储,适合 计数、查找
二、ArrayList(动态数组)
1. 为什么使用 ArrayList?
ArrayList 是 可变大小的数组,相比普通数组: ✅ 长度动态变化 ✅ 支持插入、删除 ✅ 有更多方法(add()、remove()、contains())
ArrayList 是 Java 集合框架中 List 接口的一个实现类,它基于动态数组实现,可以动态地增加或减少元素,并且允许存储重复元素,元素按照插入顺序排列。
2. ArrayList 的基本操作
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(10); // 添加元素
list.add(20);
list.add(30);
System.out.println(list.get(1)); // 访问索引 1 的元素(20)
list.remove(1); // 删除索引 1 的元素
System.out.println(list); // 输出:[10, 30]
System.out.println(list.contains(10)); // 判断是否包含 10(true)
System.out.println(list.size()); // 获取列表大小(2)
}
}
基本操作示例
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListExample {
public static void main(String[] args) {
// 创建一个 ArrayList 对象
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("apple");
list.add("banana");
list.add("cherry");
// 获取元素数量
int size = list.size();
System.out.println("列表中的元素数量: " + size);
// 访问元素
String element = list.get(1);
System.out.println("索引为 1 的元素是: " + element);
// 修改元素
list.set(1, "grape");
System.out.println("修改后索引为 1 的元素是: " + list.get(1));
// 删除元素
list.remove(2);
System.out.println("删除元素后列表内容: " + list);
// 遍历元素 - 使用 for 循环
System.out.print("使用 for 循环遍历列表: ");
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
// 遍历元素 - 使用增强 for 循环
System.out.print("使用增强 for 循环遍历列表: ");
for (String item : list) {
System.out.print(item + " ");
}
System.out.println();
// 遍历元素 - 使用迭代器
System.out.print("使用迭代器遍历列表: ");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
✅ 常用方法
方法 | 作用 |
add(value) | 添加元素 |
get(index) | 获取元素 |
remove(index) | 删除指定索引元素 |
contains(value) | 是否包含某个值 |
size() | 获取数组大小 |
3. 练习 1:去重操作
题目描述
输入 n 个整数,去除重复值,并按输入顺序输出。
输入示例
6
1 2 2 3 4 4
输出示例
1 2 3 4
Java 代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
HashSet<Integer> set = new HashSet<>();
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
int num = scanner.nextInt();
if (!set.contains(num)) {
set.add(num);
list.add(num);
}
}
for (int num : list) {
System.out.print(num + " ");
}
}
}
✅ 解题思路
- HashSet 去重
- ArrayList 保持顺序
- 时间复杂度 O(n)
⚠️ 易错点
- 直接用 HashSet 会丢失输入顺序
- 要用 ArrayList 额外存储顺序
三、HashMap(键值对存储)
1. 为什么使用 HashMap?
✅ 快速查找(平均 O(1))
✅ 存储键值对(Key-Value)
✅ 适用于 单词统计、映射关系、缓存
HashMap 是 Java 集合框架中 Map 接口的一个实现类,它基于哈希表实现,用于存储键值对(key-value),键是唯一的,值可以重复。
2. HashMap 的基本操作
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 2); // 添加键值对
map.put("banana", 5);
map.put("cherry", 3);
System.out.println(map.get("banana")); // 获取 banana 的值(5)
map.put("banana", 6); // 更新值
System.out.println(map.get("banana")); // banana 变为 6
map.remove("cherry"); // 删除键 cherry
System.out.println(map.containsKey("cherry")); // 判断是否包含 cherry(false)
System.out.println(map.size()); // 获取键值对数量(2)
}
}
基本操作示例
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapExample {
public static void main(String[] args) {
// 创建一个 HashMap 对象
HashMap<String, Integer> map = new HashMap<>();
// 添加键值对
map.put("apple", 1);
map.put("banana", 2);
map.put("cherry", 3);
// 获取键值对数量
int size = map.size();
System.out.println("映射中的键值对数量: " + size);
// 获取指定键对应的值
Integer value = map.get("banana");
System.out.println("键 'banana' 对应的值是: " + value);
// 修改键值对
map.put("banana", 5);
System.out.println("修改后键 'banana' 对应的值是: " + map.get("banana"));
// 删除键值对
map.remove("cherry");
System.out.println("删除键 'cherry' 后映射内容: " + map);
// 遍历键值对 - 使用 keySet()
System.out.print("使用 keySet() 遍历映射: ");
Set<String> keys = map.keySet();
for (String key : keys) {
System.out.print(key + ": " + map.get(key) + " ");
}
System.out.println();
// 遍历键值对 - 使用 entrySet()
System.out.print("使用 entrySet() 遍历映射: ");
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
System.out.print(entry.getKey() + ": " + entry.getValue() + " ");
}
System.out.println();
}
}
代码解释
创建对象:使用 new HashMap<>() 创建一个 HashMap 对象,这里键的类型为 String,值的类型为 Integer。
添加键值对:使用 put(K key, V value) 方法向映射中添加键值对。
获取键值对数量:使用 size() 方法获取映射中键值对的数量。
获取指定键对应的值:使用 get(Object key) 方法根据键获取对应的值。
修改键值对:使用 put(K key, V value) 方法,如果键已经存在,则会更新对应的值。
删除键值对:使用 remove(Object key) 方法删除指定键对应的键值对。
遍历键值对:可以使用 keySet() 方法获取所有键的集合,然后通过键获取对应的值;也可以使用 entrySet() 方法获取所有键值对的集合,直接遍历键值对。
✅ 常用方法
方法 | 作用 |
put(key, value) | 添加/更新键值对 |
get(key) | 获取 key 对应的值 |
remove(key) | 删除 key |
containsKey(key) | 判断 key 是否存在 |
size() | 获取键值对数量 |
3. 练习 2:统计单词频率
题目描述
输入一行单词,统计每个单词的出现次数。
输入示例
apple banana apple orange banana apple
输出示例
apple: 3
banana: 2
orange: 1
Java 代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] words = scanner.nextLine().split(" ");
HashMap<String, Integer> wordCount = new HashMap<>();
for (String word : words) {
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
}
for (Map.Entry<String, Integer> entry : wordCount.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
✅ 解题思路
- split(" ") 拆分字符串
- HashMap 记录每个单词的出现次数
- getOrDefault(word, 0) + 1 避免 null 错误
- 时间复杂度 O(n)
⚠️ 易错点
- scanner.nextLine() 读取整行
- 大小写敏感性(toLowerCase() 预处理)
去重操作
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class DuplicateRemoval {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(2);
list.add(3);
list.add(3);
list.add(3);
HashSet<Integer> set = new HashSet<>(list);
List<Integer> uniqueList = new ArrayList<>(set);
System.out.println("去重后的列表: " + uniqueList);
}
}
代码解释
首先创建一个包含重复元素的 ArrayList。
然后使用 HashSet 对 ArrayList 进行去重,因为 HashSet 不允许存储重复元素。
最后将去重后的 HashSet 转换回 ArrayList 并输出。
四、蓝桥杯集合常考点
考点 | 典型题目 | 常见难点 |
ArrayList | 去重操作 | 删除时索引变化 |
HashSet | 去重并保序 | 去重但不排序 |
HashMap | 统计次数 | getOrDefault() 防 null |
TreeMap | 排序统计 | 按键值排序 |
五、蓝桥杯集合易错点
✅ 删除元素时,索引变化
for (int i = 0; i < list.size(); i++) {
if (list.get(i) % 2 == 0) {
list.remove(i); // ❌ 错误,索引错乱
}
}
正确做法
for (int i = list.size() - 1; i >= 0; i--) { // ✅ 从后往前遍历
if (list.get(i) % 2 == 0) {
list.remove(i);
}
}
✅ HashSet 不保证顺序 ✅ HashMap 不能直接遍历
for (String key : map.keySet()) { // ✅ 先获取 key
System.out.println(key + ":" + map.get(key));
}
六、知识点总结
1. ArrayList 知识点
基于动态数组实现,支持随机访问,插入和删除操作在列表末尾效率较高,在中间位置效率较低。
常用方法包括 add()、get()、set()、remove()、size() 等。
可以使用多种方式遍历列表,如普通 for 循环、增强 for 循环和迭代器。
2. HashMap 知识点
基于哈希表实现,用于存储键值对,键是唯一的,值可以重复。
常用方法包括 put()、get()、remove()、size()、containsKey() 等。
可以使用 keySet() 或 entrySet() 方法遍历映射。
七、蓝桥杯易错点
1. 空指针异常
在使用 get() 方法从 HashMap 中获取值时,如果键不存在,会返回 null,如果直接对返回值进行操作,可能会导致空指针异常。可以使用 containsKey() 方法先判断键是否存在。
2. 并发修改异常
在使用迭代器遍历 ArrayList 或 HashMap 时,如果在遍历过程中对集合进行了添加、删除等修改操作,会抛出 ConcurrentModificationException 异常。可以使用迭代器的 remove() 方法进行删除操作。
3. 哈希冲突问题
在使用 HashMap 时,要注意哈希冲突的影响。虽然 HashMap 有自己的处理机制,但在某些情况下,哈希冲突可能会影响性能。可以通过合理选择键的类型和重写 hashCode() 和 equals() 方法来减少哈希冲突。