Java8,函数式编程应用:

持续更新中:

函数式(Functional)接口 什么是函数式(Functional)接口 只包含一个抽象方法的接口,称为函数式接口。

你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式
抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽 象方法上进行声明)。

我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检 查它是否是一个函数式接口。同时 javadoc
也会包含一条声明,说明这个 接口是一个函数式接口。

在java.util.function包下定义了Java 8 的丰富的函数式接口:

package com.ly.frauddataplatform.luoyan;//TODO: 需要在接口上定义@FunctionalInterface注解,表示这是一个函数式的接口
//TODO: MyFunc<R,T>这里是标明泛型
@FunctionalInterface
public interface MyFunc<R,T> {/*** @Author luoyan* @Description: 函数式编程* @Date 2024/3/4 20:42* @param t: 入参,泛型可以传任何类型* @return R: 返回参数,泛型可以传任何类型**/R getValue(T t);
}

这里是自定义的函数式编程的自定义的实现接口方式:

    //TODO: 这里自定义一个方法,这个方法可以实现前置通知,后置通知,可以在调用方法的前后做一些公用的操作.//TODO: 在调用到自己的实现方法中的时候,去设计实现自己所需要的代码逻辑流程./*** @Author luoyan* @Description: 封装的方法,泛型中<R,T>:这个是声明泛型,R:返回的类型,也可以修改R为String,T为String.那么入参和出现就必须是String的类型.* @Date 2024/3/4 20:46 * @param myFunc: 这个是函数方法* @param name: 入参* @return R**/public <R,T> R toUpDate(MyFunc<R, T> myFunc, T name){System.out.println("前置通知");//TODO: 调用自己设定订代码逻辑流程.R value = myFunc.getValue(name);System.out.println(value);System.out.println("后置通知");return myFunc.getValue(name);}//TODO: 使用一个方法进行测试.@Testpublic void testDemoOne(){//TODO: 这里实现自己的代码逻辑.//TODO: 这里name是T,也就是入参,"1231"是R,也就是出参,可以自己随意定义,因为是泛型.String s = toUpDate(str -> {System.out.println(str);return "1231";}, true);System.out.println(s);}

Predicate:函数接口

Predicate<Integer> predicate = n ->{if (n > 4){return true;}return false;
};Predicate<Integer> and = predicate.and(k -> {if (k < 6) {return true;}return false;
}).or(t -> {if (t == 10) {return true;}return false;
});
boolean test1 = and.test(5);
System.out.println(test1);

在这里插入图片描述

这里使用:Function接口来实现。此接口的特点:有入参,有出参,可以直接很好的使用。还有其他的函数。
在这里插入图片描述
比如:只需要入参,不需要出参,可以根据自己的情况而定。
在这里插入图片描述

举一个例子:
比如我们要使用前置要做的事情,然后调用方法自己的逻辑,最后在执行一个后置要做的事情,其中前置流程和后置流程都是共有的流程。那么就可以使用函数式的变成去封装方法,然后每个地方都可以直接调用。这样很方便。

如果没有函数式编程,我们可能会想到反射的方式,传入一个类,一个方法,然后通过反射的方式去调用这个类中的某个方法,从而可以达到这种实现,但是太麻烦了。

目前我们需要对于redis进行上锁,然后解锁,中间是走自己的流程,那么我们就可以使用函数式编程:

package com.elong.fraud.rcenginedataconvert.constants;import com.elong.fraud.rcenginedataconvert.model.dto.TryLockParamData;
import com.ly.tcbase.cacheclient.CacheClientHA;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;import javax.annotation.Resource;
import java.util.UUID;
import java.util.function.Function;/*** @Author luoyan* @Description: redis锁* @Date 2024年01月18日 10:38* @Version: V1.0*/
@Component
public class RedissionTemplate {@Resourceprivate CacheClientHA cacheClientHa;/*** @Author luoyan* @Description:* @Date 2024/1/19 15:15* @param tryLockParamData: 入参值.*                        LockKey:key,*                        param:请求参数* @param consumer: Function<T,R> *                T:入参,*                R:返回参数* @return R**/public <R> R tryLock(TryLockParamData tryLockParamData, Function<Object,R> consumer){//TODO: 前置通知,对于参数进行校验String lockKey = tryLockParamData.getLockKey();if (ObjectUtils.isEmpty(lockKey)){return null;}//TODO: 前置通知,进行上锁String lockVal = UUID.randomUUID().toString();Boolean lock = cacheClientHa.String().setnx(lockKey, 60L, lockVal);try {long millis = System.currentTimeMillis();while (!lock) {//等待锁释放try {if (System.currentTimeMillis() - millis > 3000) {throw new RuntimeException("程序异常,未获取锁!");}Thread.sleep(100);} catch (Exception ignore) {}lock = cacheClientHa.String().setnx(lockKey, 60L, lockVal);}//TODO: 这里去调用自己的代码流程return consumer.apply(tryLockParamData.getParam());}finally {//TODO: 后置通知,去进行解锁。if (lockVal.equals(cacheClientHa.String().setcas(lockKey, lockVal, lockVal))) {cacheClientHa.Key().del(lockKey);}}}
}

第一处调用:

private JSONObject saveOrUpdateOriginData(JSONObject newValue, String uniqueId, String sourceName) {//分布式锁String lockKey = String.format(RedisCacheConstants.DATA_SOURCE_DETAIL_LOCK_FORMAT, sourceName, uniqueId);//TODO:new TryLockParamData(lockKey):入参。逗号后面就是函数方法,也就是自己的代码逻辑。JSONObject newValReturn = redissionTemplate.tryLock(new TryLockParamData(lockKey), consumer -> {//TODO: 自己的代码逻辑流程,先上锁,然后走这里的代码逻辑流程,最后进行解锁。return newVal;});return newValReturn == null ? new JSONObject() : newValReturn;
}

第二处调用:

//分布式锁
String lockKey = String.format(RedisCacheConstants.FEATURE_LIST_UPDATE_LOCK_FORMAT, uniqueId);
//TODO:new TryLockParamData(lockKey):入参。逗号后面就是函数方法,也就是自己的代码逻辑。
redissionTemplate.tryLock(new TryLockParamData(lockKey), rLock -> {//TODO: 自己的代码逻辑流程,先上锁,然后走这里的代码逻辑流程,最后进行解锁。//先执行更新,更新失败执行插入int update = dcdbFraudMapper.update(origin.getTableName(), fieldList, StrUtil.toUnderlineCase(origin.getUpdateKey()), uniqueId);if (update == 0) {boolean insert = dcdbFraudMapper.insert(origin.getTableName(), fieldList);}return null;
});

可以看到上面两处的调用使用函数式编程非常方便且代码也很美观,不用其他的方式就能够快速的实现,对于同事的阅读和理解也是非常快速的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/719905.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js创建对象方式总结

js创建对象方式总结 字面量方式 使用大括号 {} 创建一个新对象&#xff0c;这是最简单直接的方式。适用于创建单个对象&#xff0c;可以直接在大括号内定义属性和方法。 let person {name: John,age: 30,gender: male};let preson2 {name: John,age: 30,gender: male};cons…

光伏发电预测

XGB、LGB在datacamp(学习网站) data fountain与国家电投系列赛,光伏发电预测 题目:给一组特征,预测瞬时发电量,训练集9000个点,测试集8000个点,特征包含光伏板的属性和外部环境等。 数据字段:ID、光伏电池板背侧温度、光伏电站现场温度、计算得到的平均转换效率、数…

MySQL学习Day25——数据库其他调优策略

一、数据库调优的措施: 1.调优的目标: (1)尽可能节省系统资源&#xff0c;以便系统可以提供更大负荷的服务 (2)合理的结构设计和参数调整&#xff0c;以提高用户操作的响应速度 (3)减少系统的瓶颈&#xff0c;提高MySQL数据库整体的性能; 2.如何定位调优:用户的反馈、日志…

stm32f103zet6笔记1-led工程

1、选择串口调试 2、LED0连接到PB5&#xff0c;PB5设置为推挽输出。PE5同理。 3、生成成对的.c,.h文件。 4、debugger选择j-link。 5、connection选择SWD。 6、编写bsp_led.c,bsp_led.h文件。 7、下载调试&#xff0c;可以看到LED0 500ms闪烁一次&#xff0c;LED1 1000ms闪烁一…

浅谈一个CTF中xss小案例

一、案例代码 二、解释 X-XSS-Protection: 0&#xff1a;关闭XSS防护 之后get传参&#xff0c;替换过滤为空&#xff0c;通过过滤保护输出到img src里面 三、正常去做无法通过 因为这道题出的不严谨所以反引号也是可以绕过的 正常考察我们的点不在这里&#xff0c;正常考察…

Unity之街机捕鱼

目录 &#x1f62a;炮台系统 &#x1f3b6;炮口方向跟随鼠标 &#x1f3b6;切换炮台 &#x1f62a;战斗系统 &#x1f3ae;概述 &#x1f3ae;单例模式 &#x1f3ae;开炮 &#x1f3ae;子弹脚本 &#x1f3ae;渔网脚本 &#x1f3ae;鱼属性信息的脚本 &#x1f6…

怎样获得CNVD原创漏洞证书

1. 前言 因为工作变动&#xff0c;我最近把这一年多的工作挖漏洞的一些工作成果提交到了CNVD漏洞平台&#xff08;https://www.cnvd.org.cn/&#xff09;&#xff0c;获得了多张CNVD原创漏洞证书。本篇博客讲下怎么获得CNVD原创漏洞证书&#xff0c;以供大家参考。 2. CNVD原创…

Canvas笔记03:Canvas元素功能、属性、获取、原理等一文讲透

hello&#xff0c;我是贝格前端工场&#xff0c;最近在学习canvas&#xff0c;分享一些canvas的一些知识点笔记&#xff0c;本期分享canvas元素的知识&#xff0c;欢迎老铁们一同学习&#xff0c;欢迎关注&#xff0c;如有前端项目可以私信贝格。 Canvas元素是HTML5中的一个重…

基于Intel x86的轨道交通/印度地铁自动售检票(AFC)系统

印度孟买地铁3号线 目前&#xff0c;印度孟买3号线正在全面建设中&#xff0c;这条全长33.5公里的线路将是孟买第一条地下地铁线路&#xff0c;设有27个地下车站和1个地面车站&#xff0c;此条线路的成功通车将连接其他地铁线路、单轨铁路、郊区铁路、城际铁路和孟买机场等&am…

解决prettier 报错 Delete `␍`

根目录&#xff08;么有的话&#xff09;新建 .prettierrc.js配置文件 module.exports {tabWidth: 2,semi: true,printWith: 80,singleQuote: true,quoteProps: consistent,htmlWhitespaceSensitivity: strict,vueIndentScriptAndStyle: true,// 主要是最后一行endOfLine:aut…

Ubuntu环境使用docker构建并运行SpringBoot镜像

今天Ubuntu环境使用docker构建并运行SpringBoot镜像&#xff0c;看文章之前建议先查看安装流程: Linux环境之Ubuntu安装Docker流程 一、镜像打包过程及执行 1、创建一个测试目录 mkdir javaDemo 2、springBoot的包复制到此目录下 cp demo1-0.0.1-SNAPSHOT.jar /data/app/…

计算机网络实验 基于ENSP的协议分析

实验二 基于eNSP的协议分析 一、实验目的&#xff1a; 1&#xff09;熟悉VRP的基本操作命令 2&#xff09;掌握ARP协议的基本工作原理 3&#xff09;掌握IP协议的基本工作原理 4&#xff09;掌握ICMP协议的基本工作原理 二、实验内容&#xff1a; 1、场景1&#xff1a;两台PC机…

React-子传父

1.概念 说明&#xff1a;React中子组件向父组件传递数据通常涉及回调函数和状态提升等方法。 2.代码实现 2.1绑定事件 说明&#xff1a;父组件绑定自定义事件 <Son onGetSonMsg{getMsg}></Son> 2.2接受事件 说明&#xff1a;子组件接受父组件的自定义事件名称…

前端食堂技术周刊第 114 期:Interop 2024、TS 5.4 RC、2 月登陆浏览器的新功能、JSR、AI SDK 3.0

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;凉拌鸡架 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 大家好&#xff0c;我是童欧巴。欢迎来到前端食堂技术周刊&#xff0c;我们先来看下…

机器学习模型总结

多元线性回归&#xff08;linear regression&#xff09; 自变量&#xff1a;连续型数据&#xff0c;因变量&#xff1a;连续型数据 选自&#xff1a;周志华老师《机器学习》P53-55 思想&#xff1a;残差平方和达到最小时的关系式子即为所求&#xff0c;残差平方和&#xff1a…

【学习心得】爬虫JS逆向通解思路

我希望能总结一个涵盖大部分爬虫逆向问题的固定思路&#xff0c;在这个思路框架下可以很高效的进行逆向爬虫开发。目前我仍在总结中&#xff0c;下面的通解思路尚不完善&#xff0c;还望各位读者见谅。 一、第一步&#xff1a;明确反爬手段 反爬手段可以分为几个大类 &#…

20240304-2-计算机网络

计算机网络 知识体系 Questions 1.计算机网络分层的优点和缺点 优点 各层之间是独立的&#xff1b;灵活性好&#xff1b;结构上可分割开&#xff1b;易于实现和维护&#xff1b;能促进标准化工作。 缺点&#xff1a; 降低效率&#xff1b;有些功能会在不同的层次中重复出现&…

微信小程序屏蔽控制台黄色提示信息

我们很多时候 一个小程序 啥都没有 终端就一直报一些黄色的警告 可以打开项目的 project.config.json 找一下setting 下面有没有 checkSiteMap 字段 如果没有加一个 如果有 直接将值改为 false 这样 再运行 就不会有这个黄色的提示信息了

第1章:绪论 1.1数据库系统概述

文章目录 1.1 数据库系统概述1.1.1 数据库的4个基本概念1.1.2 数据管理技术的产生和发展1.1.3 数据库系统的特点 1.1 数据库系统概述 1.1.1 数据库的4个基本概念 数据(Data) 是数据库中存储的基本对象 数据的定义&#xff1a;描述事物的符号记录 数据的种类&#xff1a;文本、…

Java多态性的作用及解析

多态性是 Java 面向对象编程的一个重要特性,它的主要作用包括以下几个方面: 提高代码的可扩展性:多态性使得我们可以在不修改现有代码的情况下,通过继承和重写方法来添加新的行为。这意味着我们可以在不影响现有功能的前提下,对代码进行扩展和修改。 增强代码的可读性:使…