[Java8]使用JAVA8 Lambda Expressions 实现 Monads(Functional Programming)

0x01 什么是Monads

简单说,Monad就是一种设计模式,表示将一个运算过程,通过函数拆解成互相连接的多个步骤。你只要提供下一步运算所需的函数,整个运算就会自动进行下去。
下面这两篇文章通过图解的方式讲解了什么是Monads

  • 文章一
  • 文章二

0x02 为什么要使用Monads?

一段不优雅的例子

编程时检查参数是否为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;        
}

现在我想获得user.address.street.name,常见代码如下:

 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;

这段检测代码淹没了真正取值的代码,阅读性非常不优雅

使用Monads来实现的例子

为了使用Lambda表达式,先定义一个函数接口: SingleArgExpression

package function;

/**
 * Created by haicheng.lhc on 13/04/2017.
 *
 * @author haicheng.lhc
 * @date 2017/04/13
 */
@FunctionalInterface
public interface SingleArgExpression {

    public R function(P param);
}

然后创建一个类:Option

package function;

import java.lang.reflect.ParameterizedType;

/**
 * Created by haicheng.lhc on 13/04/2017.
 *
 * @author haicheng.lhc
 * @date 2017/04/13
 */
public class Option {

    T value;

    public Option(T value) {
        this.value = value;
    }


    public  Option flatMap(SingleArgExpression> mapper) {
        if (value == null) {
            return new Option(null);
        }
        return 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() {
        System.out.println("hello");
        return value;
    }
}


接下来创建我们的测试类:OptionExample

package function;

/**
 * Created by haicheng.lhc on 13/04/2017.
 *
 * @author haicheng.lhc
 * @date 2017/04/13
 */
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 = new Option<>("alibaba"); } public static class City { public Option name; } public static void main(String[] args) { Option userOpt = new Option(new Userdetails()); //And look how simple it is now String streetName = userOpt.flatMap(user -> user.address) .flatMap(address1 -> address1.street) .flatMap(street -> street.name) .get(); System.out.println(streetName); } }

可以看出,通过这个方法获取user.address.street.name的时候,代码是非常简洁易懂的。

思路解析:
create a class Option that represents an optional value. And lets then have a map method that will run a lambda on its wrapped value and return another option. If the wrapped value is null, it will return an Option containing null without processing the lambda, thus avaoiding a null pointer exception

0x03 参考文章

https://www.javacodegeeks.com/2014/03/functional-programming-with-java-8-lambda-expressions-monads.html

你可能感兴趣的:([Java8]使用JAVA8 Lambda Expressions 实现 Monads(Functional Programming))