Java函数式编程最佳实践

这篇具有很好参考价值的文章主要介绍了Java函数式编程最佳实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

别人说烂了的stream api不就不想赘述了,我想和大家分享一下,如何用函数式编程来简化我们的开发,想说点不一样的东西
转载链接

简化事务

对于事务而言,应该粒度越小越好,并且读写逻辑应该分开,只在写的逻辑上执行事务,可以用函数式编程来简化抽去写逻辑这一步

@Service
public class TransactionService {
    @Transactional
    public void process(ThrowExceptionRunnable runnable){
        try {
            runnable.run();
        }catch (Exception e){
            new RuntimeException(e);
        }
    }
}

//使用方式
public void regist(String username){
	User user = userService.findByUserName(username);
  	if(user != null) return;
  	
  	//执行事务 注册用户 开通余额账号
  	transactionService.process(() -> {
      	userService.save(new User(username));
        balanceService.save(new Balance(username));
    });
}

赋予方法重试能力

public static void retryFunction(ThrowExceptionRunnable runnable, int time) {
        while (true) {
            try {
                runnable.run();
                return;
            } catch (Exception e) {
                time--;
                if (time <= 0) throw new RuntimeException(e);
            }
        }
    }
    public static <T, R> R retryFunction(ThrowExceptionFunction<T, R> function, T t, int time) {
        while (true) {
            try {
                return function.apply(t);
            } catch (Exception e) {
                time--;
                if (time <= 0) throw new RuntimeException(e);
            }
        }
    }
    public static <T, U, R> R retryFunction(ThrowExceptionBiFunction<T, U, R> function, T t, U u, int time) {
        while (true) {
            try {
                return function.apply(t, u);
            } catch (Exception e) {
                time--;
                if (time <= 0) throw new RuntimeException(e);
            }
        }
    }
    public static void main(String[] args) {
  	//http调用,失败会重试3次
     	retryFunction(()->http.call(),3);
  	//把数字1转成数字 失败会重试三次
  	String s = retryFunction(String::valueOf, 1, 3);
  	String ss = retryFunction(i -> String.valueOf(i), 1, 3);
    }

赋予函数缓存能力

public static <T, R> R cacheFunction(Function<T, R> function, T t, Map<T, R> cache) {
    R r = cache.get(t);
    if (r != null) return r;
    R result = function.apply(t);
    cache.put(t,result);
    return result;
}

public static void main(String[] args) {
        Map<String,User> cache = new HashMap<Integer, User>();
        String username = "张三";
  			//不走缓存
        cacheFunction(u -> userService.findByUserName(u),username,cache);
  			//走缓存
        cacheFunction(u -> userService.findByUserName(u),username,cache);
    }

赋予函数报错返回默认值能力

public static <T, R> R computeOrGetDefault(ThrowExceptionFunction<T, R> function, T t, R r) {
        try {
            return function.apply(t);
        } catch (Exception e) {
            return r;
        }
    }
    public static <R> R computeOrGetDefault(ThrowExceptionSupplier<R> supplier,R r){
        try {
            return supplier.get();
        } catch (Exception e) {
            return r;
        }
    }

	public static void main(String[] args) {
  	//返回0
  	computeOrGetDefault(i -> {
           if (i < 0) throw new RuntimeException();
           else return i;
        }, -1, 0);
  	//返回5
        computeOrGetDefault(i -> {
            if (i < 0) throw new RuntimeException();
            else return i;
        },5,0);
    }

赋予函数处理异常的能力

public static <T, R> R computeAndDealException(ThrowExceptionFunction<T, R> function, T t, Function<Exception, R> dealFunc) {
        try {
            return function.apply(t);
        } catch (Exception e) {
            return dealFunc.apply(e);
        }
    }

    public static <T, U, R> R computeAndDealException(ThrowExceptionBiFunction<T,U, R> function, T t, U u,Function<Exception, R> dealFunc) {
        try {
            return function.apply(t,u);
        } catch (Exception e) {
            return dealFunc.apply(e);
        }
    }

    public static <R> R computeAndDealException(ThrowExceptionSupplier<R> supplier, Function<Exception, R> dealFunc) {
        try {
            return supplier.get();
        } catch (Exception e) {
            return dealFunc.apply(e);
        }
    }

public static void main(String[] args) {
    //返回异常message的hashcode
    Integer integer = computeAndDealException(i -> {
        if (i < 0) throw new RuntimeException("不能小于0");
        else return i;
    }, -1, e -> e.getMessage().hashCode());
    System.out.println(integer);
  
}

赋予函数记录日志能力

public static <T, R> R logFunction(Function<T, R> function, T t, String logTitle) {
    long startTime = System.currentTimeMillis();
    log.info("[[title={}]],request={},requestTime={}", logTitle, t.toString(),
    	    LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    R apply = function.apply(t);
    long endTime = System.currentTimeMillis();
    log.info("[[title={}]],response={},spendTime={}ms", logTitle, apply.toString(), endTime - startTime);
    return apply;
}

public static void main(String[] args) {
    logFunction(String::valueOf,"s","String.valueOf");
}

自定义函数接口

    @FunctionalInterface
    public interface ThrowExceptionFunction<T, R> {
        R apply(T t) throws Exception;
    }

    @FunctionalInterface
    public interface ThrowExceptionBiFunction<T, U, R> {
        R apply(T t, U u) throws Exception;
    }
    @FunctionalInterface
    public interface ThrowExceptionSupplier<T> {
        T get() throws Exception;
    }
    @FunctionalInterface
    public interface ThrowExceptionRunnable {
        void run() throws Exception;
    }

Q:为什么要自定义函数接口

A:自带的函数接口无法处理检查异常,遇见带检查异常的方法会报错

我哪些场景用到了?

链式取数

在翻译php代码的时候我们常常遇到如下情况

$s = a.b.c.d.e.f.g

然后翻译成java代码的时候是这样的

String s = a.getB().getC().getD().getE().getF().getG();

有啥问题?没有没有判空,只要中间有一层为空,那么就是NPE,要是去写判空逻辑的话,真是要了命了

这时我们就可以用上上面提到的骚操作了

代码改写文章来源地址https://www.toymoban.com/news/detail-796240.html

String s = computeOrGetDefault(()->a.getB().getC().getD().getE().getF().getG(),"");
事务
简单的降级操作(computeAndDealException)
接口重试
接口缓存
记录日志

到了这里,关于Java函数式编程最佳实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 游戏开发的最佳编程语言及免费引擎推荐

    游戏至今仍然是人们重要的娱乐方式之一,那么哪种编程语言最适合游戏开发呢?这取决于要开发的游戏类型。例如,如果你想开发一个2D平台游戏,Lua脚本和JavaScript这样的语言比较方便。但是,如果想要开发大型3D第一人称射击游戏,那么用C++或C#之类的语言更加合适。 游

    2024年02月12日
    浏览(52)
  • Java 设计模式最佳实践:6~9

    原文:Design Patterns and Best Practices in Java 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN Java 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 这一章将描述反应式编程范式,以及为什么它能很好地适用于带有函数元素的语言。读者将熟悉反应式编程背后的概念。我们

    2023年04月14日
    浏览(55)
  • OpenCV 编译为java依赖最佳实践

    opencv 编译为java依赖最佳实践 OpenCV使用领域越来越广,但作为c++开源软件,作者更新维护并不及时,另外其他第三方java转换方式更加无法及时同步最新版本。 最新版本为4.9.0(20240124) 使用JavaCV,包含组件较多,大而全,无法及时推出stable发行版; org.bytedeco, 目前开发版兼容,

    2024年04月24日
    浏览(34)
  • JAVA OOM异常可观测最佳实践

    堆溢出-java.lang.OutOfMemoryError: Java heap space。 栈溢出-java.lang.OutOfMemorryError。 栈溢出-java.lang.StackOverFlowError。 元信息溢出-java.lang.OutOfMemoryError: Metaspace。 直接内存溢出-java.lang.OutOfMemoryError: Direct buffer memory。 GC超限-java.lang.OutOfMemoryError: GC overhead limit exceeded。 垃圾回收器就是内存

    2024年02月06日
    浏览(40)
  • Java中实现HTTPS连接的最佳实践

    引言 大家好!我是小黑。今天咱们来聊聊一个既热门又实用的话题:在Java中如何实现HTTPS连接。现在的网络世界,安全性是大家都非常关注的问题,特别是对于咱们这些程序员来说,更是如此。想想看,如果你的网站或应用数据泄露了,那得有多严重!所以,理解并实现HT

    2024年02月02日
    浏览(32)
  • 编程开发8大语言详解,为什么Java是我最推荐的?

    很多没有接触过编程语言的同学,都会觉得编程开发特别高端和神奇,担心理解不了更担心学不会。 当然,也有人会认为,你既然是做编程的,那么你应该什么都会,什么软件的开发都能完成,这是平哥经常听到的两种声音。 在此,平哥需要给大家科普一下, 编程确实改变

    2024年02月05日
    浏览(70)
  • 前端开发之函数式编程实践

    作者:京东科技 牛志伟 1、ES6中的map、filter、reduce等函数 2、React类组件 - 函数式组件+hooks、Vue3中的组合式API 3、RxJS、Lodash和Ramda等JS库 4、中间件/插件,如Redux中的applyMiddleware中间件实现 函数式编程是一种编程范式,它将程序抽象为函数和数据结构,通过函数调用来实现程序

    2024年02月04日
    浏览(33)
  • Java 中的异常类型、异常处理机制、最佳实践

    Java 异常是一种在程序运行时可能出现的错误或异常状况。它们可以由多种因素引起,例如无效输入、网络连接失败或系统资源不足等。 Java 提供了内置的异常类和处理机制,以便在程序出现异常时能够进行恰当的处理和响应。本文将探讨 Java 中的异常类型、异常处理机制以

    2024年02月08日
    浏览(59)
  • AI人工智能开发的5种最佳人工智能编程语言

    今天的AI程序员应该掌握多种语言,因为他们在跨学科的环境中工作,而不是在孤岛中工作。 虽然当前这一代人更喜欢Python,R,Java,Lisp,Prolog,Julia等 ,但前端开发人员必须了解JavaScript,Python和R的机器学习应用程序。一家知名组织的流程自动化首席开发人员了解R,Java,

    2023年04月16日
    浏览(51)
  • 面试必问的Java 线程池原理及最佳实践

    1. 概述 1.1 线程池是什么 线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如MySQL。 创建线程本身开销大,反复创建并销毁,过多的占用内存。所以有大量线程创建考虑使用线程池 。线程池不用反复创建线程达到 线程的复用 ,更具配置

    2024年02月01日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包