【Java高级编程】集合框架和泛型
目录
一、集合与数组的对比
二、Java 集合框架结构
(一)ArrayList 类(动态数组)
1. 特性
2. 常用方法
3. 示例 1:ArrayList 常用方法的动态操作
4. 示例 2:ArrayList 存储自定义对象(新闻标题)
(二)LinkedList 类(List 接口实现)
(三)Set 接口与 HashSet 类
(四)Iterator 接口(集合迭代器)
(五)Map 接口与 HashMap 类
(六)Collections 类(集合工具类)
三、泛型基础概念
(一)泛型类
定义语法
示例 10:泛型类实现泛型接口
(二)泛型接口
定义语法
(三)泛型方法
定义语法
示例 11:泛型方法的定义与调用
(四)泛型继承
示例 12:泛型父类与子类
(五)泛型在集合框架中的应用
示例 13:ArrayList 泛型化存储新闻标题
示例 14:HashMap 泛型化存储学生信息
四、习题
共用Student类
练习题 1:HashMap 存储学生姓名与成绩
练习题 2:HashMap 存储班级与学生列表
练习题 3:HashMap 嵌套存储班级与学生详情
五、总结
一、集合与数组的对比
开发中存储多个同类型数据时,数组存在明显缺陷:
- 长度固定,无法适应元素数量动态变化;
- 只能通过
length获取数组长度,无法直接获取实际存储的元素个数; - 采用连续内存存储,查找效率低。
Java 集合框架(位于java.util包)解决了数组的缺陷,更灵活实用。
二、Java 集合框架结构
核心由 3 大类接口构成:
- Collection 接口:派生
List(有序、可重复)和Set(无序、不可重复)接口; - Map 接口:存储键值对(键唯一),代表实现类
HashMap。
List接口的常用实现类:ArrayList(动态数组)、LinkedList(链表)。
(一)ArrayList 类(动态数组)
1. 特性
- 基于数组封装,长度动态可变;
- 存储于连续内存空间,遍历、随机访问元素效率高;
- 插入、删除非尾部元素时效率低(需移动后续元素)。
2. 常用方法
| 方法 | 说明 |
|---|---|
boolean add(Object o) | 向集合尾部添加元素 |
void add(int index, Object o) | 向指定索引位置添加元素(索引需在 0~ 元素个数之间) |
int size() | 返回集合中元素的个数 |
Object get(int index) | 获取指定索引的元素(返回值为Object类型,使用前需强转) |
void set(int index, Object obj) | 替换指定索引位置的元素 |
boolean contains(Object o) | 判断集合是否包含指定元素 |
int indexOf(Object obj) | 返回元素在集合中的索引(不存在则返回 - 1) |
boolean remove(Object o) | 删除指定元素 |
Object remove(int index) | 删除并返回指定索引的元素 |
3. 示例 1:ArrayList 常用方法的动态操作
import java.util.ArrayList;public class ArrayListDemo {public static void main(String[] args) {ArrayList list = new ArrayList();list.add("张三丰");list.add("郭靖");list.add("杨过");// 判断是否包含“李莫愁”System.out.println(list.contains("李莫愁")); // 输出:false// 删除索引0的元素(张三丰)list.remove(0);// 替换索引1的元素为“黄蓉”list.set(1, "黄蓉");// 遍历输出元素for (int i = 0; i < list.size(); i++) {String name = (String) list.get(i);System.out.println(name); // 输出:郭靖、黄蓉}// 输出“小龙女”的索引System.out.println(list.indexOf("小龙女")); // 输出:-1// 清空集合list.clear();// 遍历空集合(无输出)for (Object obj : list) {String name = (String) obj;System.out.println(name);}// 判断集合是否为空System.out.println(list.isEmpty()); // 输出:true}
}
4. 示例 2:ArrayList 存储自定义对象(新闻标题)
import java.util.ArrayList;
import java.util.List;// 新闻标题类:封装ID、名称、创建者
class NewTitle {private int id;private String titleName;private String creator;public NewTitle(int id, String titleName, String creator) {this.id = id;this.titleName = titleName;this.creator = creator;}public String getName() {return titleName;}
}public class NewsDemo {public static void main(String[] args) {// 创建新闻标题对象NewTitle car = new NewTitle(1, "汽车", "管理员");NewTitle test = new NewTitle(2, "高考", "管理员");// 创建ArrayList集合存储新闻List newsTitleList = new ArrayList();newsTitleList.add(car);newsTitleList.add(test);// 输出新闻总数System.out.println("新闻标题数目为:" + newsTitleList.size() + " 条");// 遍历输出新闻名称System.out.println("新闻标题名称为:");for (Object obj : newsTitleList) {NewTitle title = (NewTitle) obj;System.out.println(title.getName()); // 输出:汽车、高考}}
}
(二)LinkedList 类(List 接口实现)
- 存储结构:链表结构,插入、删除元素效率高,查找效率低。
- 常用方法:
方法 说明 void addFirst(Object obj)向集合首部插入元素 void addLast(Object obj)向集合尾部插入元素 Object getFirst()获取集合首部元素 Object getLast()获取集合尾部元素 Object removeFirst()删除并返回首部元素 Object removeLast()删除并返回尾部元素 - 示例 3:存储新闻标题并操作定义
NewTitle类(包含 ID、名称、创建者),用LinkedList实现添加、获取、删除首尾元素及遍历:import java.util.LinkedList; public class LinkedListDemo {public static void main(String[] args) {LinkedList<NewTitle> newsList = new LinkedList<>();newsList.addFirst(new NewTitle(3, "头条:今日要闻", "主编"));newsList.addLast(new NewTitle(1, "科技:AI进展", "编辑A"));System.out.println("首条新闻:" + newsList.getFirst().getName());System.out.println("删除末条:" + newsList.removeLast().getName());for(NewTitle news : newsList) {System.out.println(news.getName());}} }
(三)Set 接口与 HashSet 类
- Set 特性:存储无重复、无序元素,常用实现类
HashSet,非线程安全,允许null。 - HashSet 常用方法(表 1-3):
方法 说明 boolean add(Object o)添加元素(已存在则不添加) void clear()清空集合 int size()返回元素数量 boolean isEmpty()判断集合是否为空 boolean contains(Object o)判断是否包含元素 boolean remove(Object o)删除元素(存在则返回 true) - 示例 4:存储新闻标题并操作用
HashSet实现添加、判断包含、删除、遍历:import java.util.HashSet; import java.util.Set; // 复用NewTitle类 public class HashSetDemo {public static void main(String[] args) {Set<NewTitle> newsList = new HashSet<>();newsList.add(new NewTitle(1, "汽车", "管理员"));newsList.add(new NewTitle(2, "娱乐", "编辑B"));System.out.println("新闻总数:" + newsList.size());System.out.println("是否包含汽车新闻:" + newsList.contains(new NewTitle(1, "汽车", "管理员")));newsList.remove(new NewTitle(2, "娱乐", "编辑B"));for(NewTitle news : newsList) {System.out.println(news.getName());}} }
(四)Iterator 接口(集合迭代器)
- 作用:遍历集合元素,核心方法
hasNext()(判断是否有下一个元素)、next()(获取下一个元素)。 - 示例 5:遍历 ArrayList 集合
import java.util.ArrayList; import java.util.Iterator; public class IteratorDemo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("张三");list.add("李四");Iterator<String> it = list.iterator();while(it.hasNext()) {String name = it.next();System.out.println(name);}} }
(五)Map 接口与 HashMap 类
- Map 特性:存储键值对(key-value),键唯一、值可重复;常用实现类
HashMap,查询效率高,无序。 - HashMap 常用方法:
方法 说明 Object put(Object key, Object value)添加键值对 Object remove(Object key)删除键值对(返回被删除的值) Object get(Object key)根据键获取值 boolean containsKey(Object key)判断是否包含指定键 boolean containsValue(Object value)判断是否包含指定值 boolean isEmpty()判断集合是否为空 void clear()清空集合 int size()返回元素数量 Set keySet()获取所有键的集合 Collection values()获取所有值的集合 - 示例 6:存储学生信息并操作以 “英文名” 为键、
Student对象为值,实现添加、查询、删除、遍历:import java.util.HashMap;class Student {private String name; // 学生姓名private String gender; // 学生性别// 构造器:初始化学生姓名和性别public Student(String name, String gender) {this.name = name;this.gender = gender;}// getter方法:获取学生姓名(代码中需调用此方法)public String getName() {return name;}// getter方法:获取学生性别(可选,如需使用可调用)public String getGender() {return gender;}// setter方法:可选,用于修改属性(根据需求添加)public void setName(String name) {this.name = name;}public void setGender(String gender) {this.gender = gender;} }public class HashMapDemo {public static void main(String[] args) {// 创建HashMap集合,键为String类型(英文名),值为Student类型(学生对象)HashMap<String, Student> students = new HashMap<>();// 向集合中添加键值对(学生信息)students.put("Jack", new Student("李明", "男"));students.put("Rose", new Student("刘丽", "女"));// 输出学生总数System.out.println("学生总数:" + students.size()); // 输出:学生总数:2// 根据键"Jack"获取对应学生对象,并输出姓名System.out.println("Jack的信息:" + students.get("Jack").getName()); // 输出:Jack的信息:李明// 删除键为"Rose"的学生信息students.remove("Rose");// 遍历集合中剩余的学生信息(通过键集keySet()遍历)for (String key : students.keySet()) {Student s = students.get(key); // 根据键获取学生对象System.out.println(key + ":" + s.getName()); // 输出:Jack:李明}} }

- 示例 7:遍历 HashMap 的键和值
import java.util.HashMap; // 导入HashMap包public class HashMapTraverse {public static void main(String[] args) {HashMap<String, Student> students = new HashMap<>();students.put("Jack", new Student("李明", "男"));students.put("Rose", new Student("刘丽", "女"));System.out.println("学生英文名:");for (String key : students.keySet()) {System.out.println(key);}System.out.println("学生详细信息:");for (Student s : students.values()) {System.out.println("姓名:" + s.getName() + ",性别:" + s.getGender());}} }
(六)Collections 类(集合工具类)
- 作用:提供静态方法实现集合的排序、查找等操作;排序要求元素实现
Comparable接口。 - Comparable 接口:需重写
int compareTo(Object obj)方法,返回负整数 / 零 / 正整数表示 “小于 / 等于 / 大于” 目标对象。 - 示例 8:Student0 类实现 Comparable(按学号排序)
import java.util.ArrayList; // 实际使用时若在同一包下,可省略无关导入public class Student0 implements Comparable<Student0> {private int number; // 学号private String name; // 姓名private String gender; // 性别// 构造器public Student0(int number, String name, String gender) {this.number = number;this.name = name;this.gender = gender;}// getter/setter方法public int getNumber() { return number; }public void setNumber(int number) { this.number = number; }public String getName() { return name; }public void setName(String name) { this.name = name; }public String getGender() { return gender; }public void setGender(String gender) { this.gender = gender; }// compareTo参数类型Student0(与泛型匹配)@Overridepublic int compareTo(Student0 obj) {if (this.number == obj.number) {return 0;}return this.number > obj.number ? 1 : -1;} } - 示例 9:用 Collections 排序与查找 List 集合
import java.util.ArrayList; import java.util.Collections;public class StudentSortDemo {public static void main(String[] args) {ArrayList<Student0> students = new ArrayList<>();students.add(new Student0(3, "张三", "男"));students.add(new Student0(1, "李四", "女"));students.add(new Student0(2, "王五", "男"));// 排序(按学号升序)Collections.sort(students);// 遍历排序结果for (Student0 s : students) {System.out.println("学号:" + s.getNumber() + ",姓名:" + s.getName());}} }

三、泛型基础概念
泛型是 JDK 1.5 的特性,本质是 “参数化类型”—— 将数据类型指定为参数,实现代码复用与类型安全,避免强制类型转换。
(一)泛型类
定义语法
public class 类名<T> {private T 变量;// 构造器、方法可使用类型参数T
}
- 支持多个类型参数(如
class GenericClass<T, V>)。
示例 10:泛型类实现泛型接口
// 泛型接口
interface TestInterface<T> {T getName();
}// 泛型类实现接口
class Student1<T> implements TestInterface<T> {private T name;public void setName(T name) { this.name = name; }@Overridepublic T getName() { return name; }
}// 测试类
public class GenericsClass {public static void main(String[] args) {Student1<String> student = new Student1<>();student.setName("张三");System.out.println(student.getName()); // 输出:张三}
}
(二)泛型接口
定义语法
public interface 接口名<T> {T 方法名();
}
- 实现类需指定具体类型或继续泛型。
(三)泛型方法
定义语法
public <T> 返回值类型 方法名(T 参数) {// 方法体
}
- 类型参数
<T>需置于访问修饰符与返回值之间。
示例 11:泛型方法的定义与调用
class GenericMethod {public <T> void showSize(T obj) {System.out.println(obj.getClass().getName());}
}public class Demo {public static void main(String[] args) {GenericMethod gm = new GenericMethod();gm.showSize(10); // 输出:java.lang.Integergm.showSize("Jack");// 输出:java.lang.String}
}
(四)泛型继承
泛型类可继承,子类需指定父类的类型参数或继续泛型。
示例 12:泛型父类与子类
// 泛型父类(农场类)
class Farm<T> {protected int plantNum = 0;public void plantCrop(T crop) { plantNum++; }
}// 泛型子类(果园类,继承Farm并扩展)
class FruitFarm<T> extends Farm<T> {@Overridepublic void plantCrop(List<T> crops) {plantNum += crops.size();}
}
(五)泛型在集合框架中的应用
Java 集合(List、Set、Map)支持泛型,指定元素类型后可避免类型转换,提升安全性。
示例 13:ArrayList 泛型化存储新闻标题
import java.util.ArrayList;class NewTitle0 {private String titleName;public NewTitle0(String titleName) { this.titleName = titleName; }public String getTitleName() { return titleName; }
}public class ArrayListDemo0 {public static void main(String[] args) {ArrayList<NewTitle0> newsList = new ArrayList<>();newsList.add(new NewTitle0("汽车新闻"));newsList.add(new NewTitle0("科技新闻"));for (NewTitle0 title : newsList) {System.out.println(title.getTitleName());}}
}
示例 14:HashMap 泛型化存储学生信息
import java.util.HashMap;class Student2 {private String name;public Student2(String name) { this.name = name; }public String getName() { return name; }
}public class HashMapDemo0 {public static void main(String[] args) {HashMap<String, Student2> students = new HashMap<>();students.put("Jack", new Student2("杰克"));students.put("Rose", new Student2("罗丝"));for (String key : students.keySet()) {Student2 s = students.get(key);System.out.println(s.getName());}}
}
四、习题
共用Student类
// 学生类:包含姓名、年龄、性别、成绩等属性
public class Student {private String name; // 姓名private int age; // 年龄private String gender; // 性别private int score; // 成绩// 构造器:初始化所有属性public Student(String name, int age, String gender, int score) {this.name = name;this.age = age;this.gender = gender;this.score = score;}// getter方法:获取属性值(用于输出信息)public String getName() { return name; }public int getAge() { return age; }public String getGender() { return gender; }public int getScore() { return score; }
}
练习题 1:HashMap 存储学生姓名与成绩
创建HashMap<String, Integer>,键为学生姓名(String),值为成绩(Integer),用增强 for 循环遍历并输出成绩。
import java.util.HashMap;
import java.util.Map;public class Test1_StudentScore {public static void main(String[] args) {// 创建HashMap存储“姓名-成绩”HashMap<String, Integer> studentScores = new HashMap<>();// 添加学生数据(示例数据对应图1.9)studentScores.put("张三", 85);studentScores.put("李四", 59);studentScores.put("王五", 61);// 增强for循环遍历输出(遍历entrySet获取键值对)System.out.println("===== 学生成绩查询结果 =====");for (Map.Entry<String, Integer> entry : studentScores.entrySet()) {System.out.println(entry.getKey() + "的成绩是:" + entry.getValue());}}
}

练习题 2:HashMap 存储班级与学生列表
创建HashMap<String, ArrayList<Student>>,键为班级名称(String),值为该班级学生列表(ArrayList<Student>),获取并输出某个班级的学生信息。
import java.util.ArrayList;
import java.util.HashMap;public class Test2_ClassStudentList {public static void main(String[] args) {// 1. 创建HashMap存储“班级-学生列表”HashMap<String, ArrayList<Student>> classStudents = new HashMap<>();// 2. 为“三年级一班”创建学生列表并添加学生ArrayList<Student> class3Grade1 = new ArrayList<>();class3Grade1.add(new Student("张三", 9, "男", 85));class3Grade1.add(new Student("李四", 8, "女", 59));classStudents.put("三年级一班", class3Grade1);// 3. 为“三年级二班”创建学生列表并添加学生ArrayList<Student> class3Grade2 = new ArrayList<>();class3Grade2.add(new Student("王五", 9, "男", 61));classStudents.put("三年级二班", class3Grade2);// 4. 获取“三年级一班”的学生列表并输出(对应图1.10)System.out.println("===== 三年级一班学生列表 =====");ArrayList<Student> targetClass = classStudents.get("三年级一班");for (Student s : targetClass) {System.out.println("姓名:" + s.getName() + ",年龄:" + s.getAge() + ",性别:" + s.getGender());}}
}

练习题 3:HashMap 嵌套存储班级与学生详情
创建HashMap<String, ArrayList<Student>>,键为班级名称,值为学生列表(包含姓名、年龄、性别),输出指定班级的所有学生信息。
import java.util.ArrayList;
import java.util.HashMap;public class Test3_ClassStudentDetail {public static void main(String[] args) {// 1. 创建HashMap存储“班级-学生列表”HashMap<String, ArrayList<Student>> classDetail = new HashMap<>();// 2. 为“一年级一班”添加学生ArrayList<Student> class1Grade1 = new ArrayList<>();class1Grade1.add(new Student("孙六", 7, "男", 92));class1Grade1.add(new Student("周七", 7, "女", 88));classDetail.put("一年级一班", class1Grade1);// 3. 获取并输出“一年级一班”的所有学生信息(对应图1.11)System.out.println("===== 一年级一班学生详情 =====");System.out.println("班级名称:一年级一班");System.out.println("班级学生列表:");ArrayList<Student> students = classDetail.get("一年级一班");for (int i = 0; i < students.size(); i++) {Student s = students.get(i);System.out.println((i + 1) + ". 姓名:" + s.getName() + ",性别:" + s.getGender() + ",年龄:" + s.getAge());}}
}

五、总结
Java集合框架提供了比数组更灵活的存储方案,主要包括List(有序可重复)、Set(无序不可重复)和Map(键值对)三大接口。ArrayList基于动态数组实现,适合随机访问;LinkedList基于链表,适合频繁增删。HashSet实现Set接口,存储唯一元素;HashMap实现Map接口,提供高效键值查询。泛型可增强类型安全性,避免强制转换。Collections工具类提供排序、查找等功能。集合框架通过不同实现类满足各类数据存储需求,解决了数组长度固定、操作受限等问题。










