JAVA续本_再续java中的泛型

1

先看实例:

2853c92d2818c19ee03869afb93e03db.png

2

堆栈的实现在面试中非常流行。他们有一套相对较小的操作, 通常是push、pop, 也许还有peek。使用 java 集合 api 可以很容易地实现堆栈;不需要额外的库。花点时间, 确保你明白为什么在这里使用 linkedlist--arraylist 也能奏效吗?有什么区别?

3

对于给定的实现, 这是一个完全正常运行的堆栈, 尽管它尚未开发用于泛型。若要迁移此类以使用泛型, 可以使用编译器作为指南。首先, 必须声明 stack 类才能采用参数化类型:

public class GenericStack {

...

4

e 是参数化类型变量。任何符号都可能被使用。这里的 e 代表 "元素", 反映了它在集合 api 中的使用。包含的列表现在可以使用此泛型类型。

private final List values;

5

这将立即引发编译器错误。推送方法采用对象, 但现在需要获取 e 类型的对象:public void push(final E element) {     values.add(0, element); }

6

将值更改为 "List 还会在 stack 构造函数中引发编译器警告。创建值 linkedlist 时, 这也应参数化:

public GenericStack() {

values = new LinkedList();

}

7

编译器不知道的一个更改是对 pop 方法的更改。pop 方法的最后一行, values.remove(0) 现在返回类型为 e. 当前, 此方法返回 object。编译器没有理由出错, 甚至没有理由抛出警告, 因为 object 是所有类的超级类型, 无论 e 是什么。可以将其更改为返回类型 e:

public E pop() {

if (values.size() == 0) {

return null;

}

return values.remove(0);

}

8

继承关系的类如何影响泛型呢?

9

给定以下类层次结构:

class A {}

class B extends A {}

10

b 是 a 的子类型。但List 不是List 的子类型。java 的泛型系统被称为协方差, 无法对其进行建模。

11

在处理泛型类型时, 在某些时候, 您可能希望接受类的子类型。使用上一个问题中的 genericstack 类, 想象一个实用程序方法, 它从 a 列表中创建一个新的 genericstack:

public static GenericStack pushAllA(final List listOfA) {

final GenericStack stack = new GenericStack<>();

for (A a : listOfA) {

stack.push(a);

}

return stack;

}

12

这将完全按照 a 列表的预期方式进行编译和工作:

@Test

public void usePushAllA() {

final ArrayList list = new ArrayList<>();

for (int i = 0; i < 10; i++) {

list.add(new A());

}

final GenericStack genericStack = pushAllA(list);

System.out.println(genericStack.pop());

}

}

13

但是, 当尝试添加 b 列表时, 它不会编译:

@Test

public void usePushAllAWithBs() {

final ArrayList listOfBs = new ArrayList<>();

for(int i = 0; i < 10; i++) {

listOfBs.add(new B());

}

final GenericStack genericStack = pushAllA(listOfBs);

System.out.println(genericStack.pop());

}

14

虽然 b 是 a 的子类, 但List 不是List 的子类型。推送的方法签名需要更改以显式允许 a 和 a 的任何子类:

public static GenericStack pushAllA(final List extends A> listOfA) {}

问号称为通配符, 它告诉编译器允许扩展 a 的类的任何实例。

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值