关注公众号:”奇叔码技术“
回复:“java面试题大全”或者“java面试题”
即可免费领取资料
方便看懂Stream类的方法参数
一、适用场景:学好了能够看懂Stream类中的一些方法参数;了解概念:限制上限【可以返回值】和下限【可以添加值】和PECS原则【限制了数据的放入和取出。】
1、什么叫上限?
//上限:这个箱子容器最大为100,但是具体可以放多小的东西谁也不知道,放80,79,40,最后确定它可以放30,那都错误了,所以,没有明确的说明,那就不可以放东西为100以下的;
// 例如:我看起来最大20岁,那你可以说我18,19,15都行,但是如果我是15,那18和19就错误了;
//但是,这个箱子容器最大为100,我可以拿一个100的容器或者200的容器总之大于等于100的容器,把它装起来,所以,它是用来取即有返回值,不能放;
//又,生产者是不断创造东西得,上限就像工厂里面生产东西 【返回东西】,他就是生产者;
2、什么叫下限?
//同理:
// 下限:这个箱子容器最小为100,那我可以放比100还小的东西进去;我可以放80都行;所以,它是用来放得,不是用来取得;
//又,消费者是用东西的;下限就是我有钱,我去银行存钱,我就把钱消费给了银行;【感觉不恰当】
二、通配符<?>和类型参数T、K、V的区别?
//通配符<?>和类型参数的区别就在于,对编译器来说所有的T都代表同一种类型。比如泛型方法里,三个T都指代同一个类型,要么都是String,要么都是Integer。
//但通配符<?>没有这种约束,List<?>单纯的就表示:集合里放了一个东西,是什么我不知道。
//实际就是类型参数指明了类型,编译器知道你是什么类型;
//通配符<?>没有约束,是什么类型的我是问号不知道的,所以不能放东西;
//如果是<? extends Father > 指明上限是Father,而?是它的子类或者就是Father;
//如果是需要获取值,那就只能是利用 多态 返回的类型必须是它的基类【即父类或者自己】
三、PECS原则
/*PECS原则【限制了数据的放入和取出。】
最后看一下什么是PECS(Producer Extends Consumer Super)原则,已经很好理解了:
频繁往外读取内容的,适合用上界Extends。知道上界限 即 可以通过多态向上转型 返回其基类 Object、父类、自己、
经常往里插入的,适合用下界Super。 知道下界限 即 可以通过多态向上转型 添加其子类 子类、自己;
PESC = producer-extens , consumer -super.
如果参数化类型表示一个 T 生产者,就使用 <? extends T>; 如果它表示一个 T 消费者, 就使用 <? super T>
PESC 这个助记符突出了通配符类型的基本原则。(Get and Put Principle)
范型为List<?extends A> list,确定了上界为A,list是一个生产者,可以从list中取出数据;
为List<? super A> list,确定了下界,list 中的数据类型为A 或者A的父类,list是一个消费者:
四、上代码:
package com.jiqi.Stream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class test {
public static void main(String[] args) {
}
//<? super Father> ?比 Father还要super【大】 那Father就是最小的,即下界限 那可以放比Father还要小的;
public void floorLimit(){
ArrayList<? super Father> list = new ArrayList<>();
boolean add = list.add(new Son());
boolean add1 = list.add(new Father());
boolean add2 = list.add(new LeiFeng());
System.out.println(add);
System.out.println(add1);
System.out.println(add2);
Object object = list.get(0);
System.out.println(object);
}
//<? extends Father> ?继承于 Father 比Father 【小】 naFather就是最大的,即上界限 那可以返回比Father大的;
public void upLimit(){
List<? extends Father> list = new LinkedList<>();
// list.add(new Son()); 报错,虽然是它的子类,符合 son extends Father ;
// 但由于?通配符 是一个问号他不知道里面放了什么东西,所以编译报错;
//赋值是合法的
List<? extends Father> list1 = new ArrayList<Father>();
List<? extends Father> list2 = new ArrayList<Son>();
List<? extends Father> list3 = new ArrayList<LeiFeng>();
//取值可以,只能利用多态的形式 进行获取;
Object o = list.get(0);
Father f = list.get(0);
Human h = list.get(0);
//上界<? extends T>不能往里存,只能往外取
}
}
class Human{
}
class Father extends Human{
}
class Son extends Father{
}
class LeiFeng extends Father {
}