Java 集合 API 中的绝大多数(甚至可以说全部)组件,都支持通过泛型指定元素类型。在本教程中,我将具体演示如何为几种常见的集合类型配置泛型;通过这些示例,你将能掌握在 Java 集合 API 中使用泛型的核心方法。需要说明的是,本文的重点是 “泛型在集合中的应用”,不会展开讲解 Java 泛型的通用语法、原理等基础内容。
为 Java 集合设置泛型类型时,核心操作需在声明集合引用变量时完成。以下示例中,我们将集合(Collection)与具体实现类(HashSet)的泛型类型均指定为 String —— 这一约束意味着该集合只能存储 String 类型的实例,无法添加其他类型的对象。例如:
package com.hxstrive.java_collection;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class GenericCollectionDemo {
public static void main(String[] args) {
// 声明并实例化泛型为String的集合
Collection<String> stringCollection = new HashSet<String>();
// 向集合添加String类型元素(合法操作)
stringCollection.add("Apple");
stringCollection.add("Banana");
stringCollection.add("Cherry");
// 尝试添加非 String 类型元素(编译时会报错)
// stringCollection.add(123); // 错误: 不兼容的类型: int无法转换为String
}
}现在,该 stringCollection 只能包含字符串实例。如果试图添加其他内容,或将集合中的元素转换为 String 以外的任何其他类型,编译器会报错。
当你为 Java 集合指定了泛型类型时,该泛型类型也适用于 iterator() 方法返回的迭代器。下面的示例说明了如何获得一个设置了泛型类型的迭代器,以及迭代泛型迭代器中的元素:
package com.hxstrive.java_collection;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class GenericIteratorExample {
public static void main(String[] args) {
// 创建泛型为String的集合并添加元素
Collection<String> stringCollection = new HashSet<>();
stringCollection.add("Java");
stringCollection.add("Generics");
stringCollection.add("Iterator");
// 获取泛型为String的迭代器
Iterator<String> iterator = stringCollection.iterator();
// 迭代泛型迭代器中的元素
System.out.println("迭代器遍历结果:");
while (iterator.hasNext()) {
// 无需类型转换,直接获取String类型元素
String element = iterator.next();
// 可以直接调用String的方法,编译时类型安全
System.out.println("元素: " + element + ", 长度: " + element.length());
}
// 演示迭代过程中安全删除元素
iterator = stringCollection.iterator(); // 重新获取迭代器
while (iterator.hasNext()) {
String element = iterator.next();
if (element.length() > 6) {
iterator.remove(); // 删除长度大于6的元素
System.out.println("\n已删除元素: " + element);
}
}
// 打印删除后的集合
System.out.println("\n删除后的集合元素:");
for (String str : stringCollection) {
System.out.println(str);
}
}
}运行结果:
迭代器遍历结果: 元素: Java, 长度: 4 元素: Iterator, 长度: 8 元素: Generics, 长度: 8 已删除元素: Iterator 已删除元素: Generics 删除后的集合元素: Java
注意,泛型集合的 iterator() 方法会返回与集合相同泛型类型的迭代器(Iterator<String>),调用 iterator.next() 时无需强制类型转换,直接得到 String 类型的元素,这得益于泛型的类型信息传递。迭代器的泛型类型与集合保持一致,确保了从集合获取元素到处理元素的全流程类型安全。
你也可以使用新的 for 循环迭代上述集合,如下所示:
package com.hxstrive.java_collection;
import java.util.Collection;
import java.util.HashSet;
public class GenericForLoopDemo {
public static void main(String[] args) {
// 创建泛型为String的集合并添加元素
Collection<String> stringCollection = new HashSet<>();
stringCollection.add("Apple");
stringCollection.add("Banana");
stringCollection.add("Cherry");
stringCollection.add("Date");
// 使用增强for循环迭代泛型集合
System.out.println("集合中的元素及其长度:");
for (String stringElement : stringCollection) {
// 直接使用String类型的方法,无需类型转换
System.out.println("元素: " + stringElement + ",长度: " + stringElement.length());
}
// 演示基于泛型的业务逻辑处理
int totalLength = 0;
for (String stringElement : stringCollection) {
totalLength += stringElement.length();
}
System.out.println("\n所有元素的总长度: " + totalLength);
// 演示筛选操作
System.out.println("\n长度大于5的元素:");
for (String stringElement : stringCollection) {
if (stringElement.length() > 5) {
System.out.println("- " + stringElement);
}
}
}
}运行结果:
集合中的元素及其长度: 元素: Apple,长度: 5 元素: Cherry,长度: 6 元素: Date,长度: 4 元素: Banana,长度: 6 所有元素的总长度: 21 长度大于5的元素: - Cherry - Banana Process finished with exit code 0
注意,增强 for 循环会自动利用集合的泛型信息,变量 stringElement 直接被声明为 String 类型。循环过程中可以直接调用 String 类的方法(如 length()),无需进行类型转换,编译时即保证类型安全。相比非泛型集合的遍历,这种方式消除了 ClassCastException 的风险,代码可读性更高,无需在循环体内进行类型转换的额外操作。