Java泛型与集合对象比较:原理、实践与应用
立即解锁
发布时间: 2025-08-17 02:35:39 阅读量: 14 订阅数: 22 


Java编程基础与SCJP认证指南
### Java泛型与集合对象比较:原理、实践与应用
#### 1. 泛型基础与示例分析
泛型在Java编程中扮演着重要角色,它允许我们创建可重用的代码组件,同时提高类型安全性。下面通过一个具体的示例来深入理解泛型的使用。
```java
import java.util.Arrays;
import java.util.List;
public class GenVarArgs {
public static <T> void doIt(List<T>... aols) {
// (1)
for(int i = 0; i < aols.length; i++) {
System.out.print(aols[i] + " ");
}
}
public static void main(String... args) {
// (2)
List<String> ls1 = Arrays.asList("one", "two");
List<String> ls2 = Arrays.asList("three", "four");
List<String>[] aols = new List[] {ls1, ls2};
// (3)
doIt(aols);
// (4)
}
}
```
这个程序定义了一个泛型方法`doIt`,它接受一个可变参数的`List<T>`数组。在`main`方法中,我们创建了两个`List<String>`对象,并将它们放入一个数组中,然后调用`doIt`方法。该程序的输出结果是将数组中的每个`List`元素打印出来。
#### 2. 泛型的相关概念与特性
泛型涉及到多种类型,包括泛型类型、参数化类型和原始类型。以下是泛型的一些重要特性:
- **声明泛型类型**:可以声明泛型类和接口,以及参数化类型。
- **扩展泛型类型**:泛型类型可以被扩展,以满足不同的需求。
- **混合泛型代码和遗留代码**:在实际开发中,可能需要将泛型代码与遗留代码混合使用。
- **类型安全警告**:使用泛型时,可能会遇到未检查的警告,需要理解其对类型安全的影响。
- **通配符的子类型关系**:通配符在泛型中用于表示未知类型,需要理解其与其他类型的子类型关系。
- **类型层次结构**:了解通配符参数化类型的类型层次结构,以及引用转换的规则。
- **操作限制**:使用通配符参数化类型的引用时,需要了解`set`和`get`操作的限制。
- **有界类型参数**:可以使用有界类型参数来限制泛型类型的范围。
- **实现可迭代的泛型类**:可以实现一个既泛型又可迭代的类。
#### 3. 泛型编程练习
为了更好地掌握泛型,下面给出两个编程练习。
##### 3.1 创建多映射的泛型方法
编写一个泛型方法`toMultiMap()`,用于从给定的映射创建一个多映射。
##### 3.2 查找有向图路径上的顶点
```java
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class GraphTraversal {
public static void main(String[] args) {
// (1) Given a directed graph with five vertices:
Integer[][] neighbors = {
{1, 3}, // Vertex 0
{2}, // Vertex 1
{4}, // Vertex 2
{1, 2}, // Vertex 3
{} // Vertex 4
};
Map<Integer, Collection<Integer>> graph
= new HashMap<Integer, Collection<Integer>>();
for (int i = 0; i < neighbors.length; i++) {
graph.put(i, Arrays.asList(neighbors[i]));
}
// (2) Get start vertex.
int startVertex;
try {
startVertex = Integer.parseInt(args[0]);
} catch (ArrayIndexOutOfBoundsException ive) {
System.out.println("Usage: java GraphTraversal [0-4]");
return;
} catch (NumberFormatException nfe) {
System.out.println("Usage: java GraphTraversal [0-4]");
return;
}
Set<Integer> visitedSet = GraphTraversal.findVerticesOnPath(graph,
startVertex);
System.out.print("Vertex " + startVertex + " is connected to " + visitedSet);
}
/**
* Finds the vertices on a path from a given vertex in a directed graph.
* In the map, the key is a vertex, and the value is the collection
* containing its neighbours.
*/
public static <N> Set<N> findVerticesOnPath(Map<N,Collection<N>> graph,
N startVertex) {
// Implement the body of the method.
// Uses the generic class MyStack from Example 14.7.
}
}
```
这个练习要求实现`findVerticesOnPath`方法,用于查找有向图中从给定顶点出发的路径上的所有顶点。该方法使用了泛型,以支持不同类型的顶点。
#### 4. 集合与映射的考试目标
在Java编程中,集合和映射是非常重要的概念。以下是集合与映射的一些考试目标:
| 目标编号 | 目标描述 |
| ---- | ---- |
| 6.1 | 根据设计场景,确定应使用哪些集合类和/或接口来正确实现该设计,包括使用`Comparable`接口。 |
| 6.2 | 区分`hashCode`和`equals`方法的正确和错误重写,并解释`==`和`equals`方法的区别。 |
| 6.3 | 编写使用泛型版本的`Collections API`的代码,特别是`Set`、`List`和`Map`接口及其实现类。认识非泛型`Collections API`的局限性,并了解如何重构代码以使用泛型版本。编写使用`NavigableSet`和`NavigableMap`接口的代码。 |
| 6.4 | 开发能够正确使用类/接口声明、实例变量、方法参数和返回类型中的类型参数的代码;编写泛型方法或使用通配符类型的方法,并理解这两种方法的异同。 |
| 6.5 | 使用`java.util`包中的功能编写代码来操作列表,包括排序、执行二分查找或将列表转换为数组。使用`java.util`包中的功能编写代码来操作数组,包括排序、执行二分查找或将数组转换为列表。使用`java.util.Comparator`和`java.lang.Comparable`接口来影响列表和数组的排序。此外,认识基本包装类和`java.lang.String`的“自然排序”对排序的影响。 |
#### 5. 比较对象的重要性
在Java中,比较对象是一个常见的操作。理解如何重写`equals()`和`hashCode()`方法,以及实现`Comparable`接口,对于正确使用对象在集合和映射中非常重要。
##### 5.1 版本号类的示例
以版本号类为例,一个软件产品的版本号通常包含三个部分:发布号、修订号和补丁号。我们将实现不同版本的版本号类,并使用`TestCaseVNO`类的`test`方法进行测试。
```java
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import static java.lang.System.out;
public class TestCaseVNO {
/** Type parameter N represents a class implementing a version number. */
public static <N> void test(
// (1)
N latest,
// (2a)
N inShops,
// (2b)
N older,
// (2c)
N[] versions,
// (3)
Integer[] downloads) {
// (4)
// Print the class name.
out.println(latest.getClass());
// (5)
// Various tests.
out.println("Test object reference and value equality:");
out.printf ("
```
0
0
复制全文
相关推荐










