day40 设计模式、jdk8新特性

2023-09-14 21:39:31

一、代理模式

为其他对象提供一种代理控制此对象的访问

若一个对象不适合直接引用另一个对象,

代理对象在客户端和目标对象之间起到中介作用

组成:

抽象角色:通过接口 抽象类 真实角色实现了哪些方法

代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法

可以附加自己的操作

真实角色:实现抽象角色,定义业务逻辑,供代理角色来调用

  1. 代理模式分类

    • 静态代理

    • 动态代理

      • JDK动态代理

      • cglib动态代理

  2. 静态代理: 抽象角色固定, 代理角色和代理的真实角色是固定。

  3. 动态代理

    通过反射机制来实现的,代理角色不在是固定的角色,而是一个通用的工具类,还可以代理很多操作

动态代理是在静态代理的基础上,代理的真实角色由设置好的固定的一个变成自由的多个,实现更广泛的应用。

动态代理的代理角色类Proxyutil需要实现接口InvocationHandler

public class ProxyUtil经纪人 implements InvocationHandler {
    private Object obj;

    public Object newProxyInstance(Object obj){
        this.obj = obj;
        return Proxy.newProxyInstance(this.obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),
                this);
    };

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(obj,args);
    }
}

/**
 * 代理角色:
 */
public class 经纪人 implements InvocationHandler {
    //真实角色,由于任何角色都可以使用此工具类,所以将真实角色定义成Object
    private Object obj;

    /**
     * 功能:创建真实角色,通过调用方法,获取代理角色代理的对象
     * @return
     */
    public Object newProxyInstance(Object obj){
        this.obj = obj;
        /*
            Proxy这个类是用于设置代理
             newProxyInstance(
                              ClassLoader loader, 参数1:类的加载器
                              Class<?>[] interfaces, 参数2.类的接口
                              InvocationHandler h)  参数3: 本类的实例

          通过 newProxyInstance方法获取真实对象的接口,从而创建代理实例

         */
        Object o = Proxy.newProxyInstance(
                this.obj.getClass().getClassLoader(), //我是谁?  真实对象
                obj.getClass().getInterfaces(), //我干爹是谁? 真实对象实现的接口
                this // 代理是谁, 你要实现哪个接口
        );
        return o;
    }

    //用反射的方法调用真实角色中的方法

    /**
     *
     * @param proxy 代理对象
     * @param method 代理有哪些方法
     * @param args 包含传入代理实例上方法调用的参数值的对象数组
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(obj,args);
    }
}

 经纪公司 经纪公司 = new 经纪公司() {
            @Override
            public void 吃饭() {
            }
            @Override
            public void 跳舞() {
            }
            @Override
            public void 唱歌() {
            }
        };

代理类实现了所代理的接口,可以在调用代理类方法时调用被代理的对象实现的方法。因此,当使用动态代理时,需要将代理对象转换为被代理对象的接口类型。

二、原型模式

原型模式用于创建重复对象 保证性能  这种类型的设计属于创建创建型模式

方式是有一个原型接口

父类实现Cloneable接口 

  @Override
    protected Object clone()  {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

三、JDK8新特性

支持Lambda表达式:是一种特殊的匿名内部类形式,语法更加简洁

允许把函数作为一个方法的参数,将代码像数据一样进行传递

基本语法:

函数式接口 变量名 =  (参数,参数)—> {方法体}

注意事项:

形参列表数据类型会自动推断

如果形参列表为空,只需要保留()

如果形参只有一个,()可以省略,只需要参数名即可

如果执行的代码只有一句话且无返回值 { }可省略,

Lambda不会生成一个单独的内部类文件

四、函数式接口

如果一个接口只有  **一**个 抽象方法 该接口称之为函数式接口

函数式接口可以使用Lambda,lambda表达式会自动匹配到这个抽象方法上

@FunctionalInterface

常见的函数式接口:

Consumer消费型接口

Supplier供给型接口

Function函数型接口

Predicate 断言型接口

ackage com.oracle.methodinterface2;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * 四个常见的函数式接口
 * 1. Consumer<T>  消费型接口  表示接受单个输入参数并且不返回结果的操作
 */
public class MethodInterface {
    public static void main(String[] args) {
        //1. Consumer<T>  消费型接口
        //匿名内部类的方式
        Consumer<Double> consumer = new Consumer<Double>() {
            @Override
            public void accept(Double money) {
                System.out.println("聚餐消费:" + money);
            }
        };
        happy(consumer, 500);

        //Lambda表达式写法
        Consumer<Double> con = money -> System.out.println("聚餐消费:" + money);
        happy(con,300);

        happy(money -> System.out.println("唱歌消费:" + money),1000);
        happy(money -> System.out.println("洗澡消费" + money),2000);
        happy(money -> System.out.println("足疗消费" + money),3000);


        Supplier<Integer> supplier = new Supplier<Integer>() {
            @Override
            public Integer get() {
                return new Random().nextInt(100);
            }
        };

        int[] num = getNum(supplier,10);
        System.out.println(Arrays.toString(num));

        int[] num1 = getNum(() -> new Random().nextInt(100),8);
        System.out.println(Arrays.toString(num1));


       // 3. Function<T,R>
        String str = handlerStr(s -> s.toUpperCase(), "zhangsan");
        System.out.println(str);

        String str2 = handlerStr(s -> s.trim(), "      zhang       ");
        System.out.println(str2);


        //4. //4.Predicate<T>  的使用
        List<String> names = new ArrayList<>();
        names.add("张三丰");
        names.add("张无忌");
        names.add("宋远桥");
        names.add("俞莲舟");
        names.add("俞岱岩");
        names.add("张松溪");
        names.add("张翠山");
        names.add("殷梨亭");
        names.add("莫声谷");

        List<String> list = filterName(s -> s.startsWith("张"), names);
        System.out.println(list);


    }

    // 1.Consumer<T>  消费型接口
    public static void happy(Consumer<Double> con, double money) {
        con.accept(money);
    }

    //2. SUpplier 供给型接口  给方法提供数据
    public static int[] getNum(Supplier<Integer>sup,int count){
        int[] arr = new int[count];
        for (int i = 0; i < count; i++) {
            arr[i] = sup.get();
        }
        return arr;
    }

    //3. Function<T,R>    函数式接口  对传入数据进行操作后返回 T 传入的数据,  R 返回的数据
    public static String handlerStr(Function<String,String> fun,String str){
        return  fun.apply(str);
    }

    //4.Predicate<T>  断言型接口  判断,返回boolean类型
    public static List<String> filterName(Predicate<String> pre, List<String> list){
        List<String> resultList = new ArrayList<>();
        for (String s : list) {
            if(pre.test(s)){
                resultList.add(s);
            }
        }
        return resultList;
    }

}

五、方法引用

方法应用是Lambda表达式的一种简写形式。如果lambda表达式只是调用类已经存在的方法、则可以使用方法引用。

对象::实例方法

 类::静态方法

类::实例方法

类::new

  //1. 对象::实例方法
        Consumer<String> con = s -> System.out.println(s);
        con.accept("Hello");

        Consumer<String> con2 = System.out::println;
        con2.accept("World");

        //2. 类::静态方法
        /**
         *  static int compare(int x, int y)
         * 比较两个 int数字值。
         */
       // Comparator<Integer> com = (o1,o2)->Integer.compare(o2,o1);
        Comparator<Integer> com2 = Integer::compare;
        Set<Integer> set = new TreeSet<>(com2);
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(4);
        set.add(5);
        set.add(6);
        set.add(7);
        System.out.println(set);

        // 类::实例方法
        Function<Student,String> fun = s -> s.getName();
        Function<Student,String> fun2 = Student::getName;

        //类::new
        Supplier<Student> sup = () ->new Student();
        Supplier<Student> sup2 = Student::new;

        Student student = sup2.get();
        System.out.println(student);

        List<String> list = new ArrayList<>();
        list.add("宋江");
        list.add("卢俊义");
        list.add("公孙胜");
        list.add("吴用");
        list.add("关胜");
        list.add("林冲");

        //list.forEach(s-> System.out.println(s));
        list.forEach(System.out::println);

    }
}

更多推荐

pycharm 中package, directory, sources root, resources root的区别

【遇到的问题】导入yolov5中有utils文件,自己的代码中也有utils文件,使得yolov5中的这部分引用出错了。【解决方案】单独建立detection文件夹,把检测相关的都放在这里,yolov5是github上拉取的源码,发现yolov5中fromutilsimport...有下划线,且会认为是edgeserv

多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出

多输入多输出|MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出目录多输入多输出|MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出预测效果基本介绍程序设计往期精彩参考资料预测效果基本介绍MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出1.dat

【码银送书第七期】七本考研书籍

八九月的朋友圈刮起了一股晒通知书潮,频频有大佬晒出“研究生入学通知书”,看着让人既羡慕又焦虑。果然应了那句老话——比你优秀的人,还比你努力。心里痒痒,想考研的技术人儿~别再犹豫了。小编咨询了一大波上岸的大佬,这份备考书单给大家参考。专业课(此处特指408,全称计算机专业基础综合)知识点超级多,题目灵活,数据结构、计算机

考研408 | 【计算机组成原理】 数据的表示和运算

进位计数制十进制计数法:推广:r进制计数法任意进制-->十进制:二进制<-->八进制、十六进制:各种进制的常见书写方式:十进制-->任意进制:十进制-->二进制(拼凑法):真值和机器数:总结:BCD码总结:无符号整数的表示和运算无符号整数在计算机中的应用:无符号整数的表示:无符号整数的加法运算:无符号整数的减法运算:总

uniapp运行到IOS真机提示 错误:请查看是否设备未加入到证书列表或者确认证书类型是否匹配

参考文章:请查看是否设备未加入到证书列表或者确认证书类型是否匹配ios开发描述文件必须绑定调试设备,只有授权的设备才可以直接安装基座,所以在申请开发描述文件之前,先添加调试的IOS设备。前往网站https://developer.apple.com,在Devices中,添加手机设备UUID第一步:登录第二步:检查设备列

VHOST-SCSI代码分析(1)VHOST SCSI设备模拟

VHOSTSCSI设备的模拟是由QEMU和HOST共同实现的,QEMU模拟VHOSTSCSI设备配置空间等,而对于虚拟机通知HOST和HOST通知虚拟机机制由HOST内核实现。在QEMU中VHOSTSCSI设备继承关系如下:其它设备以及对应class_init函数和realize具现化实现与VIRTIO-SCSI一致,

Learn Prompt-为什么用 ChatGPT API?

引用人工智能先驱吴恩达先生说过的话:“一个系统需要的远不止一个提示(prompt)或者一个对LLM(大性语言模型)的调用。”API的优点:集成更深:通过API,您可以将ChatGPT集成到自己的系统和工作流中,实现更深层次的定制和控制。个性化的响应:您可以根据特定需求和场景调整模型的响应,例如,通过改变温度(tempe

华策影视AIGC工程师招聘; 百度大模型创业松;主流大语言模型的技术原理细节;AIGC Prompt的七个缺陷 | ShowMeAI日报

👀日报&周刊合集|🎡生产力工具与行业应用大全|🧡点赞关注评论拜托啦!🎯华策影视AIGC工程师招聘,AIGC在「文娱领域」的真正落地逛即刻时发现关注的AI博主@杨昌发布了自己公司的招聘信息,而且附上了团队氛围和工作感受等分享。华策影视是影视行业龙头企业,成立了AIGC应用研究院,重视AI且不算卷。岗位base上海

Learn Prompt-ChatGPT 精选案例:学习各国语言

过去,我们学语言需要花费很多时间来学习各种材料,再联系老师修改口语、作文等,十分费时费力。有了ChatGPT之后,我们就相当于有一个免费的,实时反馈的语言学习助手,大大节省了我们的时间。下面我将以英文的雅思学习为例子,结合口语和写作,介绍如何利用ChatGPT来学习语言。口语​插件安装​正式开始之前,我们要先完成插件的

安防监控系统/视频云存储/视频监控平台EasyCVR无法级联上级平台,该如何解决?

安防视频监控系统EasyCVR平台能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放,可同时播放多路视频流,也能支持视频定时轮播。视频监控管理平台EasyCVR支持多种播放协议,包括:HLS、HTTP-F

【视频】Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析|数据分享...

全文下载链接:http://tecdat.cn/?p=23544在本文中,长短期记忆网络——通常称为“LSTM”——是一种特殊的RNN递归神经网络,能够学习长期依赖关系(点击文末“阅读原文”获取完整代码数据)。本文使用降雨量数据(查看文末了解数据免费获取方式)进行分析。视频:LSTM神经网络架构和工作原理及其在Pyth

热文推荐