java lambda if_使用Java8的Lambda实现Monda -解道Jdon

使用Java8的Lambda实现Monad

Monad是函数语言(Cojure或Scala)中的设计模式概念, 那么现在为什么在Java中变得如此重要?因为Java从版本8以后引入了新的Lambda特性,Lambda或闭包是函数语言的特征,它允许你使用代码块作为一个变量,并且让你将它传递。

首先我们假设一个不使用Monad的场景:空值Null检查:

public static class Userdetails{

public Address address;

public Name name;

}

public static class Name{

public String firstName;

public String lastName;

}

public static class Address{

public String houseNumber;

public Street street;

public City city;

}

public static class Street{

public String name;

}

public static class City{

public String name;

}

现在你要从UserDetails访问其street接到名称,有可能是空的,不用Monad你也许是如下进行检查:

if(user == null )

return null;

else if(user.address == null)

return null;

else if(user.address.street == null)

return null;

else

return user.address.street.name;

这是非常琐碎和噪音的。

让我们创建一个Option类代表一个可选值,然后有一个围绕其运行lambda的map方法,该方法返回另外一个可选值。如果围绕的值是一个null, 它会返回一个Option,其中包含null, 这样避免空指针出现,注意map方法需要使用一个lambda作为参数,但是我们需要首先创建一个接口SingleArgExpression 支持它。因为在Java8中使用函数接口表达lambda:

public interface SingleArgExpression

{

public R function(P param);

}

准备好了函数接口,这样我们可以将SingleArgExpression的lambda作为参数传递了,下面是Option.java,关键是其中的map方法,该方法参数是SingleArgExpression的lambda。

public class Option {

T value;

public Option(T value){

this.value = value;

}

//核心重要方法map 如果是空就不应用lambda,否则就可以使用lambda

public Option map(SingleArgExpression mapper){

if(value == null){

return new Option(null);

}else{

return new Option(mapper.function(value));

}

}

@Override

public boolean equals(Object rhs){

if(rhs instanceof Option){

Option o = (Option)rhs;

if(value == null)

return (o.value==null);

else{

return value.equals(o.value);

}

}else{

return false;

}

}

@Override

public int hashCode(){

return value==null? 0 : value.hashCode();

}

public T get(){

return value;

}

}

下面我们重新编写Userdetails如下:

public class OptionExample{

public static class Userdetails{

public Option

address = new Option<>(null);

public Option name = new Option<>(null);

}

public static class Name{

public Option firstName = new Option(null);

public Option lastName = new Option(null);

}

public static class Address{

public Option houseNumber;

public Option street;

public Option city;

}

public static class Street{

public Option name;

}

public static class City{

public Option name;

}

public static void main(String [] args){

Option userOpt =  new Option<>(new Userdetails());

//现在变得很简单了。

String streetName = userOpt.flatMap(user -> user.address).map(address -> address.street).map(street -> street.name).get();

System.out.println(streetName);

}

}

核心代码如下:

String streetName = userOpt.flatMap(user -> user.address).map(address -> address.street).map(street -> street.name).get();

这样就不用担心返回空值抛出空指针错误了。

现在UserDetails的所有方法都是返回一个Option了,这确保方法的使用者了解返回值可能会为空。

为了避免核心代码中每次都调用get(), 我们使用类似flatMap替代map:

public Option flatMap(SingleArgExpression> mapper){

if(value == null){

return new Option(null);

}

return  mapper.function(value);

}

上面方法其实是一个过滤器,它让我们放入一个if条件在map链中, 这样只有当条件为真是获得一个值,注意这也是空安全null-safe。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值