🎉 恭喜你发现了宝藏!

Java集合框架入门:ArrayList与HashMap实战指南(新手必学)

温馨提示:本文最后更新于2025-12-26 16:35:57,某些文章具有时效性,若有错误或已失效,请在下方留言或联系社长

Java编程中,集合框架是处理批量数据的核心工具,相比数组,集合具有“动态扩容、支持泛型、提供丰富操作方法”等优势,广泛应用于日常开发。新手初期常被数组的固定长度限制困扰,而ArrayList(动态数组)和HashMap(键值对存储)作为集合框架中最常用的两个实现类,几乎覆盖了80%以上的基础数据存储场景。很多新手容易混淆集合与数组的区别、ArrayList与HashMap的适用场景,也不清楚如何正确使用它们的核心方法。本文将从集合框架核心认知、ArrayList实战(有序可重复)、HashMap实战(无序键唯一)、集合与数组转换、常见问题解决方案五个维度,系统讲解Java集合框架的基础使用,帮助新手快速掌握并灵活运用。

本文核心要点:Java集合框架核心概念、ArrayList核心方法与实战、HashMap核心方法与实战、集合与数组转换技巧、新手常见问题避坑指南

一、Java集合框架核心认知

在学习具体集合类之前,首先要明确“什么是集合框架”以及“集合与数组的区别”,建立对集合的基础认知。

1.1 集合框架的定义与核心作用

Java集合框架(Java Collections Framework)是一套用于存储和操作批量数据的类和接口的总称,位于java.util包下。其核心作用是:

  • 动态存储数据:无需提前指定长度,可根据数据量自动扩容(解决数组固定长度的痛点);
  • 提供丰富操作:内置增删改查、排序、遍历等方法,无需手动实现(如ArrayList的add、remove方法);
  • 支持泛型安全:通过泛型指定存储的数据类型,避免类型转换错误(如ArrayList<String>仅存储字符串);
  • 适配不同场景:提供多种集合类型(有序/无序、可重复/不可重复),满足不同业务需求(如ArrayList有序可重复,HashMap无序键唯一)。

1.2 集合与数组的核心区别

新手常混淆集合与数组,二者的核心区别如下表所示,明确区别有助于选择合适的存储方式:

对比维度 数组 集合(如ArrayList、HashMap)
长度特性 长度固定,创建后无法修改 长度动态,可自动扩容
存储类型 可存储基本类型(int、char)和引用类型 仅存储引用类型(基本类型需使用包装类,如int→Integer)
操作方法 无内置方法,增删改查需手动实现 内置丰富方法(add、remove、get、contains等)
适用场景 数据量固定、简单存储场景 数据量不固定、需要频繁增删改查的场景

1.3 集合框架核心体系

Java集合框架核心接口分为两大分支:Collection(存储单个元素)和Map(存储键值对元素),新手初期重点掌握以下实现类:

  • Collection分支:存储单个元素,核心实现类:
  • ArrayList:动态数组,有序、可重复,查询快、增删慢(末尾增删快);
  • LinkedList:链表,有序、可重复,增删快、查询慢;
  • HashSet:哈希表,无序、不可重复,查询和增删都快。
  • Map分支:存储键值对(key-value),核心实现类:
  • HashMap:哈希表,无序、key唯一,查询和增删都快(开发首选);
  • TreeMap:红黑树,有序(按key自然排序)、key唯一,查询和增删效率中等;
  • Hashtable:哈希表,无序、key唯一,线程安全,效率低(基本淘汰)。

提示:新手初期优先掌握ArrayList(对应有序可重复场景)和HashMap(对应键值对存储场景),这两个类覆盖了大部分基础开发需求。

二、ArrayList实战:动态数组的增删改查

ArrayList是List接口的实现类,底层基于数组实现,具有“有序、可重复”的特性,查询效率高(通过索引直接访问),适合需要频繁查询、数据有序的场景(如存储学生列表、商品列表)。

2.1 ArrayList核心语法

Plain Text
// 1. 导入ArrayList类(java.util包下)
import java.util.ArrayList;// 2. 创建ArrayList对象(指定存储类型,泛型语法)
ArrayList<数据类型> list = new ArrayList<>();// 示例:创建存储String类型的ArrayList
ArrayList<String> strList = new ArrayList<>();
// 示例:创建存储Integer(int包装类)类型的ArrayList
ArrayList<Integer> intList = new ArrayList<>();

注意:ArrayList仅支持引用类型,若需存储基本类型(如int、double),需使用对应的包装类(int→Integer、double→Double)。

2.2 ArrayList核心方法实战

ArrayList提供了丰富的增删改查方法,以下是最常用方法的实战案例:

Plain Text
import java.util.ArrayList;public class ArrayListDemo {
public static void main(String[] args) {
// 1. 创建ArrayList(存储String类型)
ArrayList<String> fruits = new ArrayList<>();// 2. 增:添加元素(add方法)
fruits.add(“Apple”); // 添加单个元素到末尾
fruits.add(“Banana”);
fruits.add(1, “Orange”); // 插入元素到指定索引(索引1)
System.out.println(“添加元素后:” + fruits); // 输出:[Apple, Orange, Banana]// 3. 查:获取元素(get方法)、获取长度(size方法)
String firstFruit = fruits.get(0); // 获取索引0的元素
int size = fruits.size(); // 获取集合长度(元素个数)
System.out.println(“第一个元素:” + firstFruit); // 输出:Apple
System.out.println(“集合长度:” + size); // 输出:3// 4. 改:修改元素(set方法)
fruits.set(2, “Grape”); // 将索引2的元素改为Grape
System.out.println(“修改元素后:” + fruits); // 输出:[Apple, Orange, Grape]// 5. 删:删除元素(remove方法)
fruits.remove(1); // 删除指定索引的元素(索引1)
// fruits.remove(“Apple”); // 也可直接删除指定元素
System.out.println(“删除元素后:” + fruits); // 输出:[Apple, Grape]// 6. 判断:是否包含某个元素(contains方法)
boolean hasApple = fruits.contains(“Apple”);
System.out.println(“是否包含Apple:” + hasApple); // 输出:true

// 7. 遍历:三种常用遍历方式
System.out.println(“\n遍历集合:”);
// 方式1:普通for循环(需索引,可修改元素)
for (int i = 0; i < fruits.size(); i++) {
System.out.println(“索引[” + i + “]:” + fruits.get(i));
}

// 方式2:增强for循环(无需索引,仅读取元素)
for (String fruit : fruits) {
System.out.println(“元素:” + fruit);
}

// 方式3:清空集合(clear方法)
fruits.clear();
System.out.println(“清空后集合:” + fruits); // 输出:[]
}
}

运行结果:

Plain Text
添加元素后:[Apple, Orange, Banana]
第一个元素:Apple
集合长度:3
修改元素后:[Apple, Orange, Grape]
删除元素后:[Apple, Grape]
是否包含Apple:true遍历集合:
索引[0]:Apple
索引[1]:Grape
元素:Apple
元素:Grape
清空后集合:[]

2.3 ArrayList实战案例:学生列表管理

需求:使用ArrayList实现学生列表的增删改查,存储学生姓名和年龄,实现添加学生、删除学生、查询学生、遍历学生功能。

Plain Text
import java.util.ArrayList;// 学生类(存储学生信息)
class Student {
private String name;
private int age;// 构造方法
public Student(String name, int age) {
this.name = name;
this.age = age;
}// getter方法(获取属性值)
public String getName() {
return name;
}public int getAge() {
return age;
}// 重写toString方法(便于打印学生信息)
@Override
public String toString() {
return “Student{name='” + name + “‘, age=” + age + “}”;
}
}public class StudentListManager {
public static void main(String[] args) {
// 1. 创建ArrayList(存储Student类型)
ArrayList<Student> studentList = new ArrayList<>();

// 2. 添加学生(增)
studentList.add(new Student(“张三”, 18));
studentList.add(new Student(“李四”, 19));
studentList.add(new Student(“王五”, 17));
System.out.println(“添加学生后:” + studentList);

// 3. 查询学生(查)
Student firstStudent = studentList.get(0);
System.out.println(“\n第一个学生:” + firstStudent);

// 4. 修改学生(改:将索引1的学生年龄改为20)
Student student = studentList.get(1);
// 注意:需通过学生对象的setter方法修改属性(此处省略setter,直接修改的话需添加)
// 补充setter方法后可写:student.setAge(20);
System.out.println(“\n修改后学生列表:” + studentList);

// 5. 删除学生(删:删除索引2的学生)
studentList.remove(2);
System.out.println(“\n删除学生后:” + studentList);

// 6. 遍历学生
System.out.println(“\n遍历所有学生:”);
for (Student s : studentList) {
System.out.println(s);
}
}
}

运行结果:

Plain Text
添加学生后:[Student{name=’张三’, age=18}, Student{name=’李四’, age=19}, Student{name=’王五’, age=17}]第一个学生:Student{name=’张三’, age=18}修改后学生列表:[Student{name=’张三’, age=18}, Student{name=’李四’, age=19}, Student{name=’王五’, age=17}]删除学生后:[Student{name=’张三’, age=18}, Student{name=’李四’, age=19}]遍历所有学生:
Student{name=’张三’, age=18}
Student{name=’李四’, age=19}

三、HashMap实战:键值对的增删改查

HashMap是Map接口的实现类,底层基于哈希表实现,具有“无序、key唯一”的特性,查询和增删效率都很高,适合需要通过“键”快速查找“值”的场景(如存储用户信息:key为用户名,value为用户对象;存储配置信息:key为配置项名称,value为配置值)。

3.1 HashMap核心语法

Plain Text
// 1. 导入HashMap类(java.util包下)
import java.util.HashMap;// 2. 创建HashMap对象(指定key和value的类型,泛型语法)
HashMap<key类型, value类型> map = new HashMap<>();// 示例:创建key为String、value为Integer的HashMap
HashMap<String, Integer> scoreMap = new HashMap<>();
// 示例:创建key为Integer、value为Student的HashMap
HashMap<Integer, Student> studentMap = new HashMap<>();

核心特性:HashMap的key是唯一的,若添加重复的key,新的value会覆盖旧的value;value可以重复。

3.2 HashMap核心方法实战

HashMap提供了针对键值对的增删改查方法,以下是最常用方法的实战案例:

Plain Text
import java.util.HashMap;
import java.util.Set;public class HashMapDemo {
public static void main(String[] args) {
// 1. 创建HashMap(key:String类型,value:Integer类型)
HashMap<String, Integer> scoreMap = new HashMap<>();// 2. 增:添加键值对(put方法)
scoreMap.put(“张三”, 95);
scoreMap.put(“李四”, 88);
scoreMap.put(“王五”, 92);
scoreMap.put(“张三”, 98); // 重复key,覆盖旧value(95→98)
System.out.println(“添加键值对后:” + scoreMap); // 输出:{李四=88, 张三=98, 王五=92}(无序)// 3. 查:获取value(get方法,通过key获取)
Integer zhangsanScore = scoreMap.get(“张三”);
System.out.println(“\n张三的分数:” + zhangsanScore); // 输出:98// 4. 改:修改value(put方法,重复key即可覆盖)
scoreMap.put(“李四”, 90); // 将李四的分数改为90
System.out.println(“修改后:” + scoreMap); // 输出:{李四=90, 张三=98, 王五=92}// 5. 删:删除键值对(remove方法,通过key删除)
scoreMap.remove(“王五”);
System.out.println(“删除王五后:” + scoreMap); // 输出:{李四=90, 张三=98}// 6. 判断:是否包含指定key/value
boolean hasZhangsan = scoreMap.containsKey(“张三”);
boolean hasScore90 = scoreMap.containsValue(90);
System.out.println(“\n是否包含key=张三:” + hasZhangsan); // 输出:true
System.out.println(“是否包含value=90:” + hasScore90); // 输出:true

// 7. 遍历:两种常用遍历方式
System.out.println(“\n遍历方式1:遍历所有key,再获取value”);
Set<String> keys = scoreMap.keySet(); // 获取所有key的集合
for (String key : keys) {
Integer value = scoreMap.get(key);
System.out.println(key + “:” + value);
}

System.out.println(“\n遍历方式2:直接遍历键值对(entrySet)”);
for (HashMap.Entry<String, Integer> entry : scoreMap.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + “:” + value);
}

// 8. 清空集合(clear方法)
scoreMap.clear();
System.out.println(“\n清空后:” + scoreMap); // 输出:{}
}
}

运行结果:

Plain Text
添加键值对后:{李四=88, 张三=98, 王五=92}张三的分数:98
修改后:{李四=90, 张三=98, 王五=92}
删除王五后:{李四=90, 张三=98}是否包含key=张三:true
是否包含value=90:true遍历方式1:遍历所有key,再获取value
李四:90
张三:98遍历方式2:直接遍历键值对(entrySet)
李四:90
张三:98清空后:{}

3.3 HashMap实战案例:用户信息管理

需求:使用HashMap实现用户信息管理,key为用户ID(唯一),value为用户对象(存储用户名和密码),实现添加用户、查询用户、修改密码、删除用户功能。

Plain Text
import java.util.HashMap;// 用户类
class User {
private String username;
private String password;// 构造方法
public User(String username, String password) {
this.username = username;
this.password = password;
}// getter和setter方法
public String getUsername() {
return username;
}public void setPassword(String password) {
this.password = password;
}// 重写toString方法
@Override
public String toString() {
return “User{username='” + username + “‘, password='” + password + “‘}”;
}
}public class UserMapManager {
public static void main(String[] args) {
// 1. 创建HashMap(key:Integer类型(用户ID),value:User类型)
HashMap<Integer, User> userMap = new HashMap<>();

// 2. 添加用户(增)
userMap.put(1, new User(“admin”, “123456”));
userMap.put(2, new User(“test1”, “test001”));
userMap.put(3, new User(“test2”, “test002”));
System.out.println(“添加用户后:” + userMap);

// 3. 查询用户(查:通过用户ID获取用户)
User admin = userMap.get(1);
System.out.println(“\n用户ID=1的信息:” + admin);

// 4. 修改密码(改:通过用户ID获取用户,再修改密码)
User test1 = userMap.get(2);
test1.setPassword(“newtest001”);
System.out.println(“\n修改test1密码后:” + userMap.get(2));

// 5. 删除用户(删:通过用户ID删除)
userMap.remove(3);
System.out.println(“\n删除用户ID=3后:” + userMap);

// 6. 遍历用户
System.out.println(“\n遍历所有用户:”);
for (HashMap.Entry<Integer, User> entry : userMap.entrySet()) {
Integer userId = entry.getKey();
User user = entry.getValue();
System.out.println(“用户ID:” + userId + “,用户信息:” + user);
}
}
}

运行结果:

Plain Text
添加用户后:{1=User{username=’admin’, password=’123456′}, 2=User{username=’test1′, password=’test001′}, 3=User{username=’test2′, password=’test002′}}用户ID=1的信息:User{username=’admin’, password=’123456′}修改test1密码后:User{username=’test1′, password=’newtest001′}删除用户ID=3后:{1=User{username=’admin’, password=’123456′}, 2=User{username=’test1′, password=’newtest001′}}遍历所有用户:
用户ID:1,用户信息:User{username=’admin’, password=’123456′}
用户ID:2,用户信息:User{username=’test1′, password=’newtest001′}

四、集合与数组的转换

在实际开发中,经常需要在集合和数组之间转换(如将ArrayList转为数组传给旧接口,将数组转为ArrayList便于操作)。以下是最常用的转换方法:

4.1 ArrayList转数组

使用ArrayList的toArray()方法,推荐指定数组类型(避免类型转换错误):

Plain Text
import java.util.ArrayList;public class ArrayListToArray {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add(“Apple”);
list.add(“Banana”);
list.add(“Orange”);// 方式1:转成Object[](不推荐,需要强制类型转换)
Object[] objArr = list.toArray();// 方式2:转成指定类型的数组(推荐)
String[] strArr = list.toArray(new String[0]); // new String[0]指定返回数组类型System.out.println(“ArrayList转数组后:”);
for (String s : strArr) {
System.out.println(s);
}
}
}

4.2 数组转ArrayList

使用Arrays.asList()方法(注意:返回的是固定长度的List,不能添加/删除元素;若需可修改,需重新创建ArrayList):

Plain Text
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class ArrayToArrayList {
public static void main(String[] args) {
String[] strArr = {“Apple”, “Banana”, “Orange”};// 方式1:直接转换(返回固定长度List,不可添加/删除)
List<String> fixedList = Arrays.asList(strArr);
// fixedList.add(“Grape”); // 错误:UnsupportedOperationException(不支持添加)// 方式2:转换为可修改的ArrayList(推荐)
List<String> modifiableList = new ArrayList<>(Arrays.asList(strArr));
modifiableList.add(“Grape”); // 可以正常添加System.out.println(“数组转可修改ArrayList后:” + modifiableList); // 输出:[Apple, Banana, Orange, Grape]
}
}

五、集合框架常见问题与解决方案(新手避坑指南)

整理新手在使用集合框架时高频出现的错误,结合具体场景给出解决方案,帮助快速排查问题。

问题1:ArrayList存储基本类型报错

原因:ArrayList仅支持引用类型,直接存储基本类型(如int、char)会导致编译器错误。

解决方案:使用基本类型对应的包装类(int→Integer、char→Character、double→Double)。

Plain Text
// 错误示例:直接存储int
// ArrayList<int> list = new ArrayList<>();// 正确示例:使用包装类Integer
ArrayList<Integer> list = new ArrayList<>();
list.add(10); // 自动装箱(int→Integer)
int num = list.get(0); // 自动拆箱(Integer→int)

问题2:HashMap添加重复key未覆盖

原因:新手误以为HashMap的key可以重复,或未注意到“重复key会覆盖旧value”的特性。

解决方案:确保key的唯一性;若需存储重复key对应的多个value,可使用HashMap<K, List<V>>(key对应value列表)。

Plain Text
// 示例:存储重复key的多个value
HashMap<String, List<Integer>> map = new HashMap<>();
// 给key=张三添加多个分数
List<Integer> scores = new ArrayList<>();
scores.add(95);
scores.add(98);
map.put(“张三”, scores);
System.out.println(“张三的所有分数:” + map.get(“张三”)); // 输出:[95, 98]

问题3:遍历集合时修改元素导致ConcurrentModificationException

原因:使用增强for循环遍历集合时,直接调用集合的remove/add方法修改集合结构,会触发快速失败机制,抛出并发修改异常。

解决方案:使用迭代器(Iterator)的remove方法修改,或使用普通for循环(ArrayList)。

Plain Text
import java.util.ArrayList;
import java.util.Iterator;public class ConcurrentModificationDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add(“Apple”);
list.add(“Banana”);
list.add(“Orange”);// 错误示例:增强for循环遍历并删除
// for (String s : list) {
//     if (s.equals(“Banana”)) {
//         list.remove(s); // 抛出ConcurrentModificationException
//     }
// }// 正确示例1:使用迭代器删除
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (s.equals(“Banana”)) {
iterator.remove(); // 迭代器的remove方法
}
}// 正确示例2:普通for循环删除(ArrayList)
// for (int i = 0; i < list.size(); i++) {
//     if (list.get(i).equals(“Banana”)) {
//         list.remove(i);
//         i–; // 注意:删除后索引需减1,避免跳过元素
//     }
// }System.out.println(“删除后:” + list); // 输出:[Apple, Orange]
}
}

问题4:Arrays.asList()转换的List无法添加/删除元素

原因:Arrays.asList()返回的是java.util.Arrays.ArrayList(内部类),并非java.util.ArrayList,该内部类是固定长度的,不支持添加/删除操作。

解决方案:将其重新包装为java.util.ArrayList(如new ArrayList<>(Arrays.asList(数组)))。

Plain Text
String[] strArr = {“Apple”, “Banana”};
// 错误:返回的List不可修改
// List<String> list = Arrays.asList(strArr);
// list.add(“Orange”);// 正确:包装为可修改的ArrayList
List<String> list = new ArrayList<>(Arrays.asList(strArr));
list.add(“Orange”); // 正常执行

六、总结

本文系统讲解了Java集合框架的核心知识,重点实战了最常用的ArrayList(动态数组)和HashMap(键值对存储),包括它们的核心方法、适用场景、实战案例,以及集合与数组的转换技巧。集合框架是Java编程的基础工具,掌握ArrayList和HashMap的使用,能大幅提升处理批量数据的效率,解决数组固定长度的痛点。

新手学习集合框架的关键是“理解特性+多动手实践”——通过编写不同场景的代码(如列表管理、键值对存储),熟悉ArrayList和HashMap的核心方法,明确它们的适用场景(有序可重复用ArrayList,键值对查询用HashMap),同时注意规避存储基本类型、并发修改、固定长度List等常见错误。如果在学习过程中有其他问题,欢迎在评论区留言讨论。

关键词:Java集合框架、Java ArrayList、Java HashMap、集合与数组转换、Java新手教程、集合实战

此文章仅供学习 请在下载24小时内删除。
© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

    也~一个评论的都没有