你以为你真的懂lamda表达式?

前言

在读完这篇文章后,https://baijiahao.baidu.com/s?id=1715197622860689960&wfr=spider&for=pc,我首先问了自己如标题的问题。在具体的实践过程中,发现了自己更多的不足点,记录并形成本文。

map

对于第一阶段的Lazy定义,大多数人都能够实现,但在完成supervisor定义时(一个惰性值计算另一个惰性值)存在了疑惑,首先第一次我的定义如下:

@Data
public class User {
    private Long uid;
    private Lazy department = Lazy.of(() -> {
        final String byId = DepartmentService.getById(uid);
        return byId;
    });
    private String supervisor = department.map(p -> {
        final String byDepatId = SupervisorService.getByDepatId(p);
        return byDepatId;
    });
    private Set permission;
}

此时在测试用例中,发现department的返回失效,uid一直是空(即使已经提前设置了uid),猜测难道在类加载时,就已经执行了department.map,通过断点方式,果真如此。断点顺序如图1,2,3

你以为你真的懂lamda表达式?

你以为你真的懂lamda表达式?

那这样一来,department.map已经不是惰性,转头一想,也确实如此。这里的supervisor被定义成了String,而非Supplier。需要通过Lazy.of继承包装,修改如下:

 public  Lazy map(Function function) {
        return Lazy.of(() -> function.apply(get()));
    }
    //声明
   	private Lazy supervisor = department.map(p -> {
   	final String byDepatId = SupervisorService.getByDepatId(p);
        return byDepatId;
    });

同时在supervisor中执行中department get是使用的缓存值。

进一步,就目前的lamda表达式,组合如下:

组合情况

分析

supervisor与supervisor

可行,意义不大

supervisor与consumer

可行

consumer与supervisor

可行,意义不大

consumer与consumer

可行,意义不大

supervisor与Function

可行,即文中所演示

Function与supervisor

可行

Function与Function

可行

Function与consumer

可行

consumer 与Function

可行,意义不大

flatmap

吸取之前教训,首先permission肯定也是一个Lazy,并且需要department和supervisor这两个值,如下是参考答案

 private Lazy>> permission = department.map(departId -> supervisor.map(supervisorId -> {
        return PermissionService.getPermission(departId, supervisorId);
    }));

其中的问题是返回值,变成了Lazy>>不够优雅。

我自行定义的结构是:

   private Lazy> permission2 = supervisor.map(supervisorId -> {
        return PermissionService.getPermission(department.get(), supervisorId);
    });

当然写出如上代码,本质上对于函数式编程还是理解不够透彻。

解决上述Lazy>>,类似地我们可以想到flatMap

实现上,保证Lazy.of包装一个单纯的supplier

 public  Lazy flatMap(Function> function) {
        return Lazy.of(() -> function.apply(get()).get());
    }

懒加载

最终用例输出一致

 public static void main(String[] args) {
        User user = new User();
        //注意这行一定要在调用department前,所以可以将该定义成final并用@NotNull进行标识
        user.setUid(1L);
        final String department = user.getDepartment().get();
        System.out.println(department);
        final String supervisor = user.getSupervisor().get();
        System.out.println(supervisor);
         Set strings = user.getPermission2().get();
        strings.forEach(System.out::println);
        strings = user.getPermission3().get();
        strings.forEach(System.out::println);
        strings = user.getPermission().get().get();
        strings.forEach(System.out::println);
    }
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章