Java泛型集合类与批量数据操作
立即解锁
发布时间: 2025-08-18 02:33:40 阅读量: 4 订阅数: 13 

Java编程入门与进阶指南
### Java泛型集合类与批量数据操作
#### 1. 通配符类型参数的使用
在Java中,当我们定义一个方法时,有时会遇到类型参数的继承问题。例如,有一个方法声明如下:
```java
public void addItems(ArrayList<Object> list) {
// 方法体未显示
}
```
思考一下,下面的语句能编译通过吗?
```java
addItems(new ArrayList<String>());
```
答案是不能。虽然`String`是`Object`的子类,但在形式类型参数方面,继承并非如此简单。这里需要使用泛型的另一个特性——通配符。
如果想创建一个接受任何类型`ArrayList`的方法,可以这样编写:
```java
public void addItems(ArrayList<?> list)
```
这里的问号表示可以是任何类型。
若要将参数限制为特定超类的集合,比如在一个薪资系统中,有一个`Employee`超类,以及`HourlyEmployee`和`SalariedEmployee`两个子类,想让方法接受`Employee`、`HourlyEmployee`或`SalariedEmployee`对象的`ArrayList`,可以在通配符后添加`extends`子句:
```java
public void addItems(ArrayList<? extends Employee> list)
```
如果`addItems`方法出现在一个使用形式类型参数`<E>`的泛型类中,且希望该方法接受类型为`E`或其任何子类的`ArrayList`,则声明如下:
```java
public void addItems(ArrayList<? extends E> list)
```
这里的通配符类型参数`<? extends E>`表示`ArrayList`可以是`E`类型或任何扩展`E`的类型。
#### 2. 泛型队列类
现在来看一个实现队列的泛型类`GenQueue`。队列是一种允许在集合末尾添加对象,并从顶部移除对象的集合类型,常用于各种应用程序,从数据处理应用到复杂的网络系统。
`GenQueue`类具有以下方法:
- `enqueue`:将对象添加到队列末尾。
- `dequeue`:从队列中检索第一个项目,并在过程中从队列中移除该项目。如果队列为空,该方法返回`null`。
- `hasItems`:如果队列中至少有一个项目,则返回`true`。
- `size`:返回队列中项目的数量。
- `addItems`:接受另一个`GenQueue`对象作为参数,将该队列中的所有项目添加到当前队列中,并移除传入队列中的所有项目。`GenQueue`参数必须与当前队列类型相同或为其子类型。
以下是`GenQueue`类的完整代码:
```java
import java.util.*;
public class GenQueue<E> {
private LinkedList<E> list = new LinkedList<E>();
public void enqueue(E item) {
list.addLast(item);
}
public E dequeue() {
return list.poll();
}
public boolean hasItems() {
return !list.isEmpty();
}
public int size() {
return list.size();
}
public void addItems(GenQueue<? extends E> q) {
while (q.hasItems())
list.addLast(q.dequeue());
}
}
```
下面是该类的主要亮点分析:
- 类声明指定了形式类型参数`<E>`,用户可以为队列元素指定类型。
- 使用私有`LinkedList`对象`list`来存储项目。
- `enqueue`方法接受类型为`E`的参数,使用`LinkedList`的`addLast`方法将项目添加到队列末尾。
- `dequeue`方法返回类型为`E`的值,使用`LinkedList`的`poll`方法返回列表中的第一个项目。
- `hasItems`方法返回`LinkedList`的`isEmpty`方法的相反值。
- `size`方法返回`LinkedList`的`size`方法的结果。
- `addItems`方法接受一个`GenQueue`对象作为参数,该对象的元素类型必须与当前`GenQueue`对象的元素类型相同或为其子类型。使用`while`循环将传入队列中的所有项目添加到当前队列中。
以下是一个测试`GenQueue`类的程序:
```java
public class GenQueueTest {
public static void main(String[] args) {
GenQueue<Employee> empList;
empList = new GenQueue<Employee>();
GenQueue<HourlyEmployee> hList;
hList = new GenQueue<HourlyEmployee>();
hList.enqueue(new HourlyEmployee("Trump", "Donald"));
hList.enqueue(new HourlyEmployee("Gates", "Bill"));
hList.enqueue(new HourlyEmployee("Forbes", "Steve"));
empList.addItems(hList);
while (empList.hasItems()) {
Employee emp = empList.dequeue();
System.out.println(emp.firstName + " " + emp.lastName);
}
}
}
class Employee {
public String lastName;
public String firstName;
public Employee() {}
public Employee(String last, String first) {
this.lastName = last;
this.firstName = first;
}
public String toString() {
return firstName + " " + lastName;
}
}
class HourlyEmployee extends Employee {
public double hourlyRate;
public HourlyEmployee(String last, String first) {
super(last, first);
}
}
```
这个程序首先创建一个可以容纳`Employee`对象的`GenQueue`对象`empList`,然后创建一个可以容纳`HourlyEmployee`对象的`GenQueue`对象`hList`,并将三个新员工添加到`hList`队列中。接着调用`empList`队列的`addItems`方法将这些员工从`hList`队列转移到`empList`队列中。最后,使用`while`循环打印`empList`队列中的员工信息。
当运行这个程序时,控制台将输出:
```
Donald Trump
Bill Gates
Steve Forbes
```
这表明`addItems`方法成功地将`hList`队列中的员工转移到了`empList`队列中。
#### 3. 钻石操作符的使用
在使用泛型时,创建泛型类型的变量并使用构造函数实例化对象时,需要两次指定类型,这比较麻烦。例如,创建一个`String`类型的`ArrayList`,需要这样编写:
```java
ArrayList<String> nums = new ArrayList<String>();
```
这里`String`类型必须指定两次,一
0
0
复制全文


