java函数式编程感悟

2020/09/23

前言

虽然工作经验增长,接触的语言也越多,也渐渐开始理解其他语言的多范式。写了一段时间scala再回来写java,重新思考了一下java8引入lambda的函数式接口,虽然是语法糖,但是可以看出java想把函数提升至一等公民的想法。这里我分享一个我自己的总结,从一个很小的功能实现,希望对大家有一些帮助。

业务的多种实现

假设我们我们的业务就是下面引用的操作,我们尝试用几种不同的写法来实现

有一个含有数字的数组,需要对数组里面的元素进行复杂的处理, 例如先放大2.5倍, 然后把它变成字符串后面加一个'分'字

代码写到方法里面

public class Test {
  
  public static void main(String[] args) {
    List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);  
    
    List<String> collect = list.stream().map(num -> (num * 2.5) + "fen").collect(Collectors.toList());
  }
 
}

上面是直接把代码写在循环里面,我们经常这样写,简单代码量(例如这个假设的业务,就比较适合这种),但是缺点也非常明显。代码无法复用,假设处理逻辑比较复杂写在里面非常没有结构性。

其实我是非常不建议使用这种方法,java8引入labmda非常强调函数式接口,方法引用编程,如果你在stream里面的算子里面写自己的代码,代码阅读者需要花很长时间去弄清楚逻辑,但是假如你定义一个见名知意的变量,然后在算子里面引用。对方看到变量名就知道你这一步是在做什么,不必花费很长时间去阅读里面的细节。这样能做到代码简介高效可维护。

代码定义赋值给变量

public class Test {
  
  public static void main(String[] args) {
    List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);  
    
    Function<Integer, String> fun = num -> (num * 2.5) + "fen";
    List<String> collect2 = list.stream().map(fun::apply).collect(Collectors.toList());
  }
  
}

第二种是jdk1.8的接口变成,提升到抽象层面可以简单复用, 简单代码量需要复用比较适合这种, 主要写起来比较简单。

定义方法

public class Test {
  
  public static void main(String[] args) {
    List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);  
    
    List<String> collect1 = list.stream().map(Test::convert).collect(Collectors.toList());
  }
  
  public static String convert(int num) {
      return (num * 2.5) + "fen";
  }
  
}

第三种也是我们比较常见的方法,如果业务复杂并且有多出复用情况, 应当把定义方法调用使用, 记得取一个见名知意的好方法。但是有时候复用比较低,人也比较懒可以用其他方式使用这种就有点杀鸡用牛刀了。

后言

随着编码量的提升和阅读书籍量的扩大每次肯定都会有新的想法好感悟, 这篇文章以后我会持续更新,记录我自己的一些想法。我始终认为,语言思想层面上的东西,不管技术中间件和框架怎么变, 我觉得永远都不会过时。

(转载本站文章请注明作者和出处 没有气的汽水



┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
├ 文章已经完啦, 想要第一时间收到文章更新可以关注↓ ┤
└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘

Post Directory






下面是评论区,欢迎大家留言探讨或者指出错误哈