泛型与集合(一)
- 泛型
- 泛型的核心作用
- 泛型类型(类)
- 定义与使用
- 类型参数命名约定
- 泛型方法
- 定义与调用
- 与泛型类的区别
- 通配符
- 上界通配符
- 下界通配符
- 有界类型参数
- 类型擦除
- 集合框架
- 核心接口
- Collection 接口
- Map 接口
- Collection 接口操作的常用方法
- 基本操作
- 批量操作
- 数组操作
- 流操作方法
- List 接口及实现类
- List 接口
- List 接口概述
- List 接口常用方法
- List 接口与 Collections 接口
- ArrayList 类
- 特点与实现原理
- 构造方法
- 遍历集合元素
- 使用简单的 for 循环
- 使用增强的 for 循环
- 使用迭代器
- 双向迭代器
- 数组转换为 List 对象
- 使用 Arrays.asList() 方法
- 手动遍历数组添加到 ArrayList
- 使用 Java 8 Stream API
- 基本类型数组转换为 List
- Vector 类和 Stack 类
- Vector 类
- 概述
- 常用方法
- Stack 类
- 概述
- 常用方法
泛型
泛型的核心作用
泛型是 Java 实现代码复用和类型安全的重要机制。它允许在类、接口和方法中定义类型参数,使代码能处理多种数据类型,同时避免强制类型转换和运行时类型错误。例如,在集合中使用泛型,可确保集合中元素类型的一致性,在编译阶段就能检测出类型错误,增强代码的健壮性和可读性。
泛型类型(类)
定义与使用
定义泛型类时,通过尖括号 声明类型参数,T 可以是类、接口、数组类型(基本数据类型需使用包装类型)。以 Box 类为例:
public class Box<T> {private T content;public void setContent(T content) {this.content = content;}public T getContent() {return content;}
}
使用时,需指定具体的类型参数。从 Java 7 开始,可使用菱形语法简化创建对象的过程:
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
System.out.println(stringBox.getContent());
类型参数命名约定
类型参数命名通常使用单个大写字母作为类型参数名,常见的有 E(表示元素)、K(表示键)、V(表示值)、T(表示类型)、N(表示数字)等。遵循这些约定,能使代码更易理解。
泛型方法
定义与调用
泛型方法在方法返回值前声明类型参数 ,其作用域仅限于该方法。例如,定义一个打印数组元素的泛型方法:
public static <T> void printArray(T[] array) {for (T element : array) {System.out.print(element + " ");}System.out.println();
}
调用时,编译器会自动推断类型:
Integer[] intArr = {1, 2, 3};
printArray(intArr);
与泛型类的区别
泛型类的类型参数作用于整个类,而泛型方法的类型参数仅在声明的方法内有效。泛型方法还可以在非泛型类中定义,增加了代码的灵活性。
通配符
上界通配符
上界通配符(<?extends T>)用于限制类型为T或其子类,增强泛型的灵活性。例如,计算列表中数字元素总和的方法:
public static double sum(List<? extends Number> list) {double sum = 0;for (Number num : list) {sum += num.doubleValue();}return sum;
}
该方法可接受 List<Integer>、List<Double> 等类型的参数。
下界通配符
下界通配符(<?super T>)限制类型为 T 或其父类。比如,向列表中添加 Integer 类型元素的方法:
public static void addNumbers(List<? super Integer> list) {list.add(1);list.add(2);
}
此方法可接受 List<Number>、List<Object> 等类型的参数。
有界类型参数
使用 extends 或 super 限制类型参数的范围。例如,定义一个计算数字平方的 Calculator 类:
public class Calculator<T extends Number> {public double square(T num) {return num.doubleValue() * num.doubleValue();}
}
类型擦除
泛型在编译后会被替换为 Object 或边界类型,运行时无法获取泛型信息。例如, List 和 List 在运行时都变为 List。这是为了保持 Java 的向后兼容性,但也带来了一些局限性,如无法在运行时根据泛型类型进行不同的处理。
集合框架
核心接口
Collection 接口
是所有集合的根接口,继承了 Iterable 接口,定义了集合的基本操作方法。它的主要子接口有 List、Set、Queue,每个子接口都有不同的特性和用途。List 是有序且可重复的集合,Set 是无序且不可重复的集合,Queue 是按特定顺序处理元素的集合。
Map 接口
用于存储键值对,与 Collection 接口并列。在 Map 中,键是唯一的,值可以重复,常用于根据键快速查找值的场景。
Collection 接口操作的常用方法
基本操作
- 向集合中添加元素 e:
boolean add(E e)
- 从集合中删除指定的元素 o:
boolean remove(Object o)
- 返回集合中是否包含指定的元素 o:
boolean contains(Object o)
- 返回集合是否为空,即不包含元素:
boolean isEmpty()
- 返回集合中包含的元素个数:
int size()
- 返回包含所有元素的迭代器对象:
Iterator iterator()
- 从父接口继承的方法,在集合的每个元素上执行指定的操作:
default void forEach(Consumer<? super T>action)
以下是这些方法的代码示例:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;public class CollectionExample {public static void main(String[] args) {// 创建一个集合对象,这里以ArrayList为例,它实现了Collection接口Collection<Integer> collection = new ArrayList<>();// 测试add方法boolean addResult = collection.add(5);System.out.println("添加元素结果: " + addResult);// 测试remove方法boolean removeResult = collection.remove(5);System.out.println("删除元素结果: " + removeResult);// 测试contains方法collection.add(10);boolean containsResult = collection.contains(10);System.out.println("集合是否包含元素: " + containsResult);// 测试isEmpty方法boolean isEmptyResult = collection.isEmpty();System.out.println("集合是否为空: " + isEmptyResult);// 测试size方法int size = collection.size();System.out.println("集合元素个数: " + size);// 测试iterator方法Iterator<Integer> iterator = collection.iterator();while (iterator.hasNext()) {Integer element = iterator.next();System.out.println("迭代器遍历元素: " + element);}// 测试forEach方法collection.add(20);collection.forEach(new Consumer<Integer>() {@Overridepublic void accept(Integer integer) {System.out.println("forEach方法操作元素: " + integer);}});}
}
批量操作
- 将集合c中的所有元素添加到当前集合中:
boolean addAll(Collection<? extends E> c)
- 从当前集合中删除 c 中的所有元素:
boolean removeAll(Collection<?> c)
- 从当前集合中删除满足谓词的所有元素:
default boolean removeIf(Predicate<? super E> filter)
- 返回当前集合是否包含 c 中的所有元素:
boolean containsAll(Collection<?> c)
- 在当前集合中只保留指定集合 c 中的元素,其他元素删除:
boolean retainAll(Collection<?> c)
- 将集合清空:
void clear()
以下是这些方法的代码示例:
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Predicate;public class CollectionBatchOperationsExample {public static void main(String[] args) {