if (person != null) { Country country = person.getCountry(); if (country != null) { Province province = country.getProvince(); if (province != null) { address = province.getCity(); } } } 1.第一种方法是不改变以前的entity: 这里用Optional作为每一次返回的外壳,如果有某个位置返回了null,则会直接得到"unkonwn"。 第一种方法可以平滑的和已有的JavaBean、Entity或POJA整合,而无需改动什么,也能更轻松的整合到第三方接口中(例如spring的bean)。建议目前还是以第一种Optional的使用方法为主,毕竟不是团队中每一个人都能理解每个get/set带着一个Optional的用意。 import java.util.Optional; public class Test { public static void main(String[] args) { System.out.println(Optional.ofNullable(new Person()) .map(x->x.country) .map(x->x.provinec) .map(x->x.city) .map(x->x.name) .orElse("unkonwn")); } } class Person { Country country; } class Country { Province provinec; } class Province { City city; } class City { String name; } 第二种办法是将所有的值都用Optional来定义: import java.util.Optional; public class Test { public static void main(String[] args) { System.out.println(new Person() .country.flatMap(x -> x.provinec) .flatMap(Province::getCity) .flatMap(x -> x.name) .orElse("unkonwn")); } } class Person { Optional<Country> country = Optional.empty(); } class Country { Optional<Province> provinec; } class Province { Optional<City> city; Optional<City> getCity(){//用于:: return city; } } class City { Optional<String> name; }
Optional还提供了一个filter方法用于过滤数据(实际上Java8里stream风格的接口都提供了filter方法)。例如过去我们判断值存在并作出相应的处理: if(Province!= null){ City city = Province.getCity(); if(null != city && "guangzhou".equals(city.getName()){ System.out.println(city.getName()); }else{ System.out.println("unkonwn"); } } 现在我们可以修改为 Optional.ofNullable(province) .map(x->x.city) .filter(x->"guangzhou".equals(x.getName())) .map(x->x.name) .orElse("unkonw"); 到此,利用Optional来进行函数式编程介绍完毕。Optional除了上面提到的方法,还有orElseGet、orElseThrow等根据更多需要提供的方法。orElseGet会因为出现null值抛出空指针异常,而orElseThrow会在出现null时,抛出一个使用者自定义的异常。可以查看API文档来了解所有方法的细节。
public class Test { public static void main(String[] args) { final String text = "Hallo world!"; Optional.ofNullable(text)//显示创建一个Optional壳 .map(Test::print) .map(Test::print) .ifPresent(System.out::println); Optional.ofNullable(text) .map(s ->{ System.out.println(s); return s.substring(6); }) .map(s -> null)//返回 null .ifPresent(System.out::println); } // 打印并截取str[5]之后的字符串 private static String print(String str) { System.out.println(str); return str.substring(6); } } //Consol 输出 //num1:Hallo world! //num2:world! //num3: //num4:Hallo world! 上面的代码中创建了2个Optional,实现的功能基本相同,都是使用Optional作为String的外壳对String进行截断处理。当在处理过程中遇到null值时,就不再继续处理。我们可以发现第二个Optional中出现s->null之后,后续的ifPresent不再执行。 注意观察输出的 //num3:,这表示输出了一个""字符,而不是一个null。
Optional提供了丰富的接口来处理各种情况,比如可以将代码修改为: public class Test { public static void main(String[] args) { final String text = "Hallo World!"; System.out.println(lowerCase(text));//方法一 lowerCase(null, System.out::println);//方法二 } private static String lowerCase(String str) { return Optional.ofNullable(str).map(s -> s.toLowerCase()).map(s->s.replace("world", "java")).orElse("NaN"); } private static void lowerCase(String str, Consumer<String> consumer) { consumer.accept(lowerCase(str)); } } //输出 //hallo java! //NaN 这样,我们可以动态的处理一个字符串,如果在任何时候发现值为null,则使用orElse返回预设默认的"NaN"。 总的来说,我们可以将任何数据结构用Optional包裹起来,然后使用函数式的方式对他进行处理,而不必关心随时可能会出现的null。
https://yq.aliyun.com/articles/624440?spm=a2c4e.11153940.0.0.6a255562myIiAj