public class User { // 用户 id private Long uid; // 用户的部门,为了保持示例简单,这里就用普通的字符串 // 需要远程调用 通讯录系统 获得 private String department; // 用户的主管,为了保持示例简单,这里就用一个 id 表示 // 需要远程调用 通讯录系统 获得 private Long supervisor; // 用户所持有的权限 // 需要远程调用 权限系统 获得 private Set<String> permission;}
public boolean isSupervisor(User u1, User u2) { return Objects.equals(u1.getSupervisor(), u2.getUid());}
Supplier<Integer> a = () -> 10 + 1;int b = a.get() + 1;
/*** 为了方便与标准的 Java 函数式接口交互,Lazy 也实现了 Supplier*/public class Lazy<T> implements Supplier<T> {
private final Supplier<? extends T> supplier; // 利用 value 属性缓存 supplier 计算后的值 private T value;
private Lazy(Supplier<? extends T> supplier) { this.supplier = supplier; }
public static <T> Lazy<T> of(Supplier<? extends T> supplier) { return new Lazy<>(supplier); }
public T get() { if (value == null) { T newValue = supplier.get();
if (newValue == null) { throw new IllegalStateException("Lazy value can not be null!"); }
value = newValue; }
return value; }}
Lazy<Integer> a = Lazy.of(() -> 10 + 1);int b = a.get() + 1;// get 不会再重新计算, 直接用缓存的值int c = a.get();
public class User { // 用户 id private Long uid; // 用户的部门,为了保持示例简单,这里就用普通的字符串 // 需要远程调用 通讯录系统 获得 private Lazy<String> department; // 用户的主管,为了保持示例简单,这里就用一个 id 表示 // 需要远程调用 通讯录系统 获得 private Lazy<Long> supervisor; // 用户所含有的权限 // 需要远程调用 权限系统 获得 private Lazy<Set<String>> permission; public Long getUid() { return uid; } public void setUid(Long uid) { this.uid = uid; } public String getDepartment() { return department.get(); } /** * 因为 department 是一个惰性加载的属性,所以 set 方法必须传入计算函数,而不是具体值 */ public void setDepartment(Lazy<String> department) { this.department = department; } // ... 后面类似的省略}
Long uid = 1L;User user = new User();user.setUid(uid);// departmentService 是一个rpc调用user.setDepartment(Lazy.of(() -> departmentService.getDepartment(uid)));// ....
String department = departmentService.getDepartment(uid);Long supervisor = SupervisorService.getSupervisor(department);
在盒子中装的是类型,而不是 1 和 "1" 的原因是,盒子中不一定是单个值,比如集合,甚至是更加复杂的多值映射关系。
// 反例,不能成为函子,因为这个方法没有在盒子中如实反映 function 的映射关系public Box<S> map(Function<T,S> function) { return new Box<>(null);}
public <S> Lazy<S> map(Function<? super T, ? extends S> function) { return Lazy.of(() -> function.apply(get())); }
Lazy<String> departmentLazy = Lazy.of(() -> departmentService.getDepartment(uid));Lazy<Long> supervisorLazy = departmentLazy.map( department -> SupervisorService.getSupervisor(department));
Lazy<Lazy<Set<String>>> permissions = departmentLazy.map(department -> supervisorLazy.map(supervisor -> getPermissions(department, supervisor)));
Lazy<Long> param1Lazy = Lazy.of(() -> 2L);Lazy<Long> param2Lazy = Lazy.of(() -> 2L);Lazy<Long> param3Lazy = Lazy.of(() -> 2L);Lazy<Lazy<Lazy<Long>>> result = param1Lazy.map(param1 -> param2Lazy.map(param2 -> param3Lazy.map(param3 -> param1 + param2 + param3) ));
public <S> Lazy<S> flatMap(Function super T, Lazy extends S>> function) { return Lazy.of(() -> function.apply(get()).get()); }
Lazy<Set<String>> permissions = departmentLazy.flatMap(department -> supervisorLazy.map(supervisor -> getPermissions(department, supervisor)));
Lazy<Long> param1Lazy = Lazy.of(() -> 2L);Lazy<Long> param2Lazy = Lazy.of(() -> 2L);Lazy<Long> param3Lazy = Lazy.of(() -> 2L);Lazy<Long> result = param1Lazy.flatMap(param1 -> param2Lazy.flatMap(param2 -> param3Lazy.map(param3 -> param1 + param2 + param3) ));
do param1 <- param1Lazy param2 <- param2Lazy param3 <- param3Lazy -- 注释: do 记法中 return 的含义和 Java 完全不一样 -- 它表示将值打包进盒子里, -- 等价的 Java 写法是 Lazy.of(() -> param1 + param2 + param3) return param1 + param2 + param3
public class Lazy<T> implements Supplier<T> {
private final Supplier<? extends T> supplier;
private T value;
private Lazy(Supplier<? extends T> supplier) { this.supplier = supplier; }
public static <T> Lazy<T> of(Supplier<? extends T> supplier) { return new Lazy<>(supplier); }
public T get() { if (value == null) { T newValue = supplier.get();
if (newValue == null) { throw new IllegalStateException("Lazy value can not be null!"); }
value = newValue; }
return value; }
public <S> Lazy<S> map(Function<? super T, ? extends S> function) { return Lazy.of(() -> function.apply(get())); }
public <S> Lazy<S> flatMap(Function<? super T, Lazy<? extends S>> function) { return Lazy.of(() -> function.apply(get()).get()); }}
public class UserFactory { // 部门服务, rpc 接口 private DepartmentService departmentService; // 主管服务, rpc 接口 private SupervisorService supervisorService; // 权限服务, rpc 接口 private PermissionService permissionService; public User buildUser(long uid) { Lazy<String> departmentLazy = Lazy.of(() -> departmentService.getDepartment(uid)); // 通过部门获得主管 // department -> supervisor Lazy<Long> supervisorLazy = departmentLazy.map( department -> SupervisorService.getSupervisor(department) ); // 通过部门和主管获得权限 // department, supervisor -> permission Lazy<Set<String>> permissionsLazy = departmentLazy.flatMap(department -> supervisorLazy.map( supervisor -> permissionService.getPermissions(department, supervisor) ) ); User user = new User(); user.setUid(uid); user.setDepartment(departmentLazy); user.setSupervisor(supervisorLazy); user.setPermissions(permissionsLazy); }}
// 注意,这里的 function 是装在 lazy 里面的 public <S> Lazy<S> apply(Lazy<Function<? super T, ? extends S>> function) { return Lazy.of(() -> function.get().apply(get())); }
-- 注释: 结果为 box cbox f <*> box a <*> box b
点击阅读原文查看详情!