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。
總結
以上是生活随笔為你收集整理的java lambda if_使用Java8的Lambda实现Monda -解道Jdon的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 后端技术:JDK 8 Stream 数据
- 下一篇: linux怎么查看设备序列号,linux