编程自学指南:java程序设计开发,Java 泛型与集合框架课件
一、课程信息
课程主题
泛型与集合框架
课程目标
- 理解泛型的概念、作用和基本语法。
- 掌握集合框架的体系结构和常用集合类(如
ArrayList
、LinkedList
、HashMap
等)的使用。 - 能够运用泛型和集合框架解决实际编程问题。
课程重点
- 泛型的定义和使用。
- 集合框架中常用集合类的基本操作。
课程难点
- 泛型的类型擦除机制。
- 集合框架中不同集合类的适用场景。
二、课程导入
案例引入
假设我们要编写一个程序来存储和处理一组整数。我们可以使用数组来实现这个功能,示例代码如下:
public class IntArrayExample {
public static void main(String[] args) {
int[] intArray = new int[5];
intArray[0] = 1;
intArray[1] = 2;
// 尝试存储非整数类型会编译错误
// intArray[2] = "three";
for (int i = 0; i < intArray.length; i++) {
System.out.println(intArray[i]);
}
}
}
但是数组有一些局限性,比如长度固定。如果我们想要存储不同类型的数据,或者处理动态大小的数据集合,数组就不太方便了。这时可以考虑使用集合框架。
然而,在没有泛型之前,集合可以存储任意类型的对象,这可能会导致一些类型安全问题。例如:
import java.util.ArrayList;
import java.util.List;
public class NonGenericListExample {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add("two"); // 可以添加不同类型的元素
for (Object obj : list) {
// 可能会出现 ClassCastException
// int num = (int) obj;
System.out.println(obj);
}
}
}
这里在使用时需要进行强制类型转换,并且如果不小心添加了错误类型的元素,运行时可能会抛出 ClassCastException
。为了解决这些问题,Java 引入了泛型。
三、泛型
泛型的概念
泛型是 Java 中的一种参数化类型的机制,它允许我们在定义类、接口或方法时使用类型参数,从而实现代码的复用和类型安全。
泛型类
泛型类的定义和使用示例:
// 定义一个泛型类
class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
public class GenericClassExample {
public static void main(String[] args) {
// 创建一个存储整数的 Box 对象
Box<Integer> intBox = new Box<>();
intBox.setContent(10);
Integer num = intBox.getContent();
System.out.println(num);
// 创建一个存储字符串的 Box 对象
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String str = stringBox.getContent();
System.out.println(str);
}
}
在这个例子中,Box
类是一个泛型类,T
是类型参数。在创建 Box
对象时,我们可以指定具体的类型,如 Integer
或 String
。
泛型方法
泛型方法的定义和使用示例:
public class GenericMethodExample {
// 定义一个泛型方法
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3, 4, 5};
String[] stringArray = {"Hello", "World"};
printArray(intArray);
printArray(stringArray);
}
}
这里的 printArray
方法是一个泛型方法,<T>
表示类型参数。它可以处理不同类型的数组。
泛型接口
泛型接口的定义和使用示例:
// 定义一个泛型接口
interface Generator<T> {
T generate();
}
// 实现泛型接口
class IntegerGenerator implements Generator<Integer> {
@Override
public Integer generate() {
return (int) (Math.random() * 100);
}
}
public class GenericInterfaceExample {
public static void main(String[] args) {
Generator<Integer> generator = new IntegerGenerator();
Integer num = generator.generate();
System.out.println(num);
}
}
类型擦除
Java 中的泛型是通过类型擦除实现的。在编译时,泛型类型信息会被擦除,替换为原始类型。例如:
import java.util.ArrayList;
import java.util.List;
public class TypeErasureExample {
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
List<String> stringList = new ArrayList<>();
// 运行时类型相同
System.out.println(intList.getClass() == stringList.getClass());
}
}
这里 intList
和 stringList
在运行时的类型都是 ArrayList
,泛型类型信息被擦除了。
四、集合框架
集合框架概述
Java 集合框架是一组用于存储和操作数据的类和接口,它提供了各种数据结构和算法,方便我们进行数据的管理和处理。集合框架主要分为两大体系:Collection
体系和 Map
体系。
Collection 体系
Collection
是存储单个元素的集合的根接口,它有三个主要的子接口:List
、Set
和 Queue
。
List 接口
List
接口表示有序的集合,允许存储重复元素。常用的实现类有 ArrayList
和 LinkedList
。
ArrayList
ArrayList
是基于动态数组实现的,它可以根据需要自动调整数组的大小。示例代码如下:
import java.util.ArrayList;
import java.util.List;
public class ArrayListExample {
public static void main(String[] args) {
// 创建一个 ArrayList 对象
List<String> list = new ArrayList<>();
// 添加元素
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// 访问元素
System.out.println(list.get(0));
// 遍历元素
for (String fruit : list) {
System.out.println(fruit);
}
// 删除元素
list.remove(1);
System.out.println("After removing:");
for (String fruit : list) {
System.out.println(fruit);
}
}
}
LinkedList
LinkedList
是基于双向链表实现的,它在插入和删除操作上效率较高。示例代码如下:
import java.util.LinkedList;
import java.util.List;
public class LinkedListExample {
public static void main(String[] args) {
// 创建一个 LinkedList 对象
List<String> list = new LinkedList<>();
// 添加元素
list.add("Dog");
list.add("Cat");
list.add("Bird");
// 在指定位置插入元素
list.add(1, "Fish");
// 遍历元素
for (String animal : list) {
System.out.println(animal);
}
}
}
Set 接口
Set
接口表示不允许存储重复元素的集合。常用的实现类有 HashSet
。
HashSet
HashSet
是基于哈希表实现的,它不保证元素的顺序。示例代码如下:
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
// 创建一个 HashSet 对象
Set<String> set = new HashSet<>();
// 添加元素
set.add("Red");
set.add("Green");
set.add("Blue");
set.add("Red"); // 重复元素不会被添加
// 遍历元素
for (String color : set) {
System.out.println(color);
}
}
}
Map 体系
Map
接口用于存储键值对,每个键都是唯一的。常用的实现类有 HashMap
。
HashMap
HashMap
是基于哈希表实现的,它不保证键值对的顺序。示例代码如下:
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
// 创建一个 HashMap 对象
Map<String, Integer> map = new HashMap<>();
// 添加键值对
map.put("Apple", 10);
map.put("Banana", 20);
map.put("Cherry", 30);
// 获取值
Integer value = map.get("Banana");
System.out.println("The price of Banana is: " + value);
// 遍历键值对
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
五、泛型与集合框架的结合使用
泛型集合的优势
使用泛型集合可以提高代码的类型安全性,避免类型转换错误。例如:
import java.util.ArrayList;
import java.util.List;
public class GenericCollectionExample {
public static void main(String[] args) {
// 创建一个泛型 ArrayList
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
// 编译时会检查类型,不允许添加非 Integer 类型的元素
// intList.add("three");
for (Integer num : intList) {
System.out.println(num);
}
}
}
示例:使用泛型集合存储自定义对象
import java.util.ArrayList;
import java.util.List;
// 定义一个自定义类
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class GenericCollectionWithCustomObject {
public static void main(String[] args) {
// 创建一个存储 Student 对象的泛型 ArrayList
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("Alice", 20));
studentList.add(new Student("Bob", 21));
for (Student student : studentList) {
System.out.println(student.getName() + " is " + student.getAge() + " years old.");
}
}
}
六、课堂练习
练习 1
创建一个泛型 Stack
类,实现入栈、出栈和获取栈顶元素的功能,并使用该类存储整数。
练习 2
创建一个 HashMap
来存储学生的姓名和成绩,添加一些学生信息,然后根据用户输入的姓名查询其成绩。
七、课程总结
重点回顾
- 泛型的概念、作用和基本语法,包括泛型类、泛型方法和泛型接口。
- 集合框架的体系结构,
Collection
体系(List
、Set
)和Map
体系(HashMap
)的常用实现类及其特点。 - 泛型与集合框架的结合使用,提高代码的类型安全性。
注意事项
- 泛型的类型擦除机制可能会导致一些意想不到的问题,需要注意。
- 在选择集合类时,要根据具体的需求和场景来选择合适的集合类,例如需要频繁随机访问元素可以选择
ArrayList
,需要频繁插入和删除元素可以选择LinkedList
等。
八、课后作业
作业 1
实现一个泛型的 Pair
类,用于存储两个不同类型的对象,并提供获取和设置这两个对象的方法。
作业 2
使用集合框架实现一个简单的图书管理系统,包括添加图书、删除图书、查询图书信息等功能。图书信息可以包含书名、作者、价格等。