c++ list 获取元素_List<? extends T>和List<? super T>的区别

1、先来简单介绍一下两者

——————————————————————————————————————————

1.1、List extends T>

这里T是泛型,而?是通配符,"? extends T"表示T是父类,?是子类,该list只能容纳T类型及T类型的子类。 "? extends T"可以用下图表示

91ec0f4b420b15d79e5f9fa13445e5d2.png

因为界限在"?"的上面,因此将extends称之为上界,即extends给?限定了一个上界。

1.2、List super T>

"? super T"表示T是子类,?是父类,该list只能容纳T类型及T类型的父类。

"? super T"可以用下图表示

fee99fd49329bbce27994a5497ed2548.png

因为界限在"?"的下面,因此将super称之为下界,即super给?限定了一个下界。

2、实际使用

——————————————————————————————————————————

下面主要来看看List extends T>和List<?super T>在实际使用中的例子。

下图是我设计的类继承关系图。

f3fc9a26d1f8231dcced16f4356f0031.png

其代码如下:

//物体class WuTi{}//生物class ShengWu extends WuTi{}//动物class Animal extends ShengWu{}//猫class Cat extends Animal{}//狗class Dog extends Animal{}
2.1、先来说说List extends T>

假设现在有如下两个集合,lista限定了边界,而listb没有限定边界

List extends Animal> lista = new ArrayList<>();List listb = new ArrayList<>();
  • 显然,listb是我们最常见的用法。

    listb由于泛型的类型是确定的(即Animal类型),所以listb能添加Animal、Cat、Dog(因为猫和狗都是动物)。

  • 但是lista的泛型的类型是不确定的(即用通配符?表示的),所以lista无法添加元素,即使添加Object也不行,只能添加null。

  • lista由于容纳的是Animal及其子类,所以lista能获取元素,并且获取到的元素的类型是Animal类型准没错。

那么既然lista不能添加元素,又何来的获取元素呢?可以用以下代码实现。

//虽然List<?extends Animal>不能添加元素,但是可以借助List初始化元素List data = newArrayList<>();data.add(new Dog());data.add(new Cat());data.add(newAnimal());List extends Animal> listb = data;//获取元素,其元素类型是AnimalAnimal a1 =listb.get(0);Animal a2 =listb.get(1);Animal a3 = listb.get(2);
总结:
  • 由于只能从List extends T>中获取元素,而不能向它添加元素,所以称之为生产者。如下图。

f66eabc8a2b0704d84bac6404e31cc6f.png

2.2、接下来说说List super T>
List super Animal> listc = new ArrayList();
  • 此刻我想说的是,listc能够添加元素!
  • 是不是有人就懵了,这跟List extends T>不是一样么,都采用通配符?,泛型类型都是不确定的,为什么List extends T>不能添加元素,而List<?super T>就能添加元素呢?
  • 我的解答是:listc的泛型类型是不确定的不假,但是List super Animal>中的Animal是确定的啊,你想想,假如?表示的是ShengWu类,那么我添加Animal没错吧,因为Animal是生物啊;再假如?表示的是WuTi类,那么我添加Animal也没错,因为Animal是物体啊,哈哈。
  • 另外,既然能添加Animal,那么Animal的子类也能添加,因为猫、狗都是生物或者物体。

所以就有了如下代码

List super Animal> listc = new ArrayList(); Animal animal = new Animal(); Dog dog = new Dog(); Cat cat = new Cat(); listc.add(animal); listc.add(dog); listc.add(cat);

那么,List super T>能获取元素吗?答案是不能,因为无法确定元素的返回值类型到底是啥。

总结:
  • 由于只能向List super T>添加元素,而不能从它里面获取元素,所以称之为消费者,如下图。

18e594b3251fd2f6f4496de530ae254b.png

最后我扩展一下,PECS(Producer Extends Consumer Super)原则指的就是上述对List extends T>和List super T>的总结,即生产者对应extends ,而消费者对应super。在实际使用中,我们应当遵循这个原则。

今天的分享到这里就结束了,感谢您的阅读,觉得写得不错的文末点个赞再走鸭!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值