day14
动态代理
代理设计就是为其他对象提供一种代理以控制对这个对象的访问
代理模式的原理:
使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对于原始对象的调用都要通过这个代理对象。代理对象决定是否及何时将方法调用转到原始对象上。
public class ProxyTest {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
//通过被代理类对象去实现代理类对象
Human human = (Human)new ProxyFactory().getProxyInstance(superMan);
//调用代理类对象的方法,通过invoke()方法实际上,调用的是被代理类对象的方法
String belief = human.belief();
System.out.println(belief);
human.eat("草莓沙冰");
}
}
interface Human{
String belief();
void eat(String food);
}
//被代理类
class SuperMan implements Human{
@Override
public String belief() {
return "我有一个信仰";
}
@Override
public void eat(String food) {
System.out.println("我喜欢吃" + food);
}
}
class ProxyFactory{
public Object getProxyInstance(Object obj){
MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(obj);
//通过newProxyInstance()实现代理类对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
}
}
class MyInvocationHandler implements InvocationHandler{
private Object obj;
public void bind(Object obj){
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//当代理类对象执行方法时,会执行到这里
//method为代理类调用的方法,通过反射可以得知方法的基本信息,如方法名。
//args为形参列表
Object returnVal = method.invoke(obj, args);
return returnVal;
}
}
Lambda表达式
Lambda是一个匿名函数,Lambda表达式可以理解为一段可以传递的代码。
() -> {}
->:lambda操作符 或 箭头操作符
->左边:lambda形参列表
->右边:lambda体(其实就是重写的抽象方法的方法体)
//Lambda表达式的写法。
//当Lambda体只有一条语句时,大括号和return都可以省略
Comparator<Integer> com = (o1,o2) -> Integer.compara(o1,o2)
Lambda表示式的本质:作为函数式接口的实例
如果一个接口中,只声明了一个抽象方法,则该接口称为函数式接口。
方法引用的使用
-
使用情景:当要传递给Lambda表达式的操作,已经有了实现的方法,可以用方法引用
-
方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例,所以方法引用,也是函数式接口的实例。
-
使用格式 : 类(对象) :: 方法名
-
具体分为如下的三种情况:
对象 :: 非静态方法
类 :: 静态方法
类 :: 非静态方法
//对象 :: 实例方法
Consumer<String> con1 = str -> System.out.println(str);
con1.accept("北京");
Consumer<String> con2 = System.out::println;
con2.accept("南京");
//类 :: 静态方法
Comparator<Integer> com1 = (t1,t2) -> t1.compareTo(t2);
System.out.println(com1.compare(13, 4));
Comparator<Integer> com2 = Integer::compare;
System.out.println(com2.compare(45, 132));
//类 :: 实例方法
Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);
System.out.println(com1.compare("abc", "cde"));
Comparator<String> com2 = String :: compareTo;
System.out.println(com1.compare("abc", "cde"));
Stream API
使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询。
集合讲的是数据,Stream讲的是计算。
Stream执行流程:Stream的实例化—>一系列的中间操作(过滤,映射……)---->终止操作