2.2.5 flatMap()应用&源码解析
刚才已经通过map()获取了学生的姓名,操作非常简单。但是当产生链路获取时,map可以使用么?
如:学生->工作->公司->公司名称。现在可能大家脑袋里已经有了一个想法,就是通过map(),代
码结构如下:
studentOptional.map(Student::getJob).map(Job: :getCompany).map(Company::getName);
但是这段代码是无法通过编译的。因为根据map的学习,每一次在调用的时候,都会对Optional的泛型进行改变,最终产生多层Optional嵌套的结构。如下图所示:
对于这个问题的解决,Optional类中提供了另外一个获取值的方法flatMap()。它本身用于多层调用,同时对于结果它不会形成多个Optional,而是将结果处理成最终的一个类型的Optional。但是通过flatMap获取的返回值必须是Optional类型。而map则没有这个限制。
使用示例如下:
Optional<String> nameOptional = studentOptional.flatMap(Student::getJob).flat Map(Job::getCompany).map(Company::getName);
2.2.6 filter()应用&源码解析
在获取某个对象中的属性值时,经常会根据特定的条件进行获取。之前的编码方法通常为:
Company company = optional().get(); if("oldlu".equals(company.getName)){ sout(company); }
Optional类中也提供了数据过滤的方法filter()来实现这个需求。其会根据传入的条件进行判断,如果匹配则返回一个Optional对象并包含对应的值,否则返回一个空值的Optional
使用示例如下:
Optional<Company> company = companyOptional.filter(c -> "oldlu".equals(c.getName()));
2.2.7 orElse()应用&源码解析
在取值的时候,如果值不存在,有时我们会考虑返回一个默认值。该需求就可以通过orElse()实现。
其内部会判断值是否为null,如果不为null,则返回该值,如果为null,则返回传入的默认值。
使用示例如下:
public class Demo1 { public static void getCompanyName(Student student) { Optional<Student> studentOptional = Optional.ofNullable(student); if (studentOptional.isPresent()) { String value = studentOptional.flatMap(Student::getJob).fla tMap(Job::getCompany).map(Company::getName). orElse("default value"); System.out.println(value); } } public static void main(String[] args) { Company company = new Company(); //company.setName("oldlu"); Optional<Company> companyOptional = Optional.of(company); Job job = new Job(); job.setName("pm"); job.setCompany(companyOptional); Optional<Job> jobOptional = Optional.of(job); Student s1 = new Student(); s1.setName("张三"); s1.setJob(jobOptional); getCompanyName(s1); } }
2.2.8 orElseGet()应用&源码解析
orElseGet()也是用于当Optional中没有值时,返回默认值的方法。但是它与orElse()的区别在于,它是延迟加载的。只有当Optional中没有值是才会被调用。
区别示例如下:
1)当公司名称不存在
public class Demo1 { public static void getCompanyName(Student student) { Optional<Student> studentOptional = Optional.ofNullable(student); if (studentOptional.isPresent()) { String value1 = studentOptional.flatMap(Student::getJob).fla tMap(Job::getCompany).map(Company::getName). orElse(get("a")); String value2 = studentOptional.flatMap(Student::getJob).fla tMap(Job::getCompany).map(Company::getName). orElseGet(()->get("b")); System.out.println("a: "+value1); System.out.println("b: "+value2); } } public static String get(String name) { System.out.println(name + "执行了方 法"); return "exec"; } public static void main(String[] args) { Company company = new Company(); //company.setName("oldlu"); Optional<Company> companyOptional = Optional.of(company); Job job = new Job(); job.setName("pm"); job.setCompany(companyOptional); Optional<Job> jobOptional = Optional.of(job); Student s1 = new Student(); s1.setName("张三"); s1.setJob(jobOptional); getCompanyName(s1); } }
执行结果
a执行了方法 b执行了方法 a: exec b: exec
根据上述结果可知,当公司名称不存在时,orElse()与orElseGet()都被执行了。
2)公司名称存在
public class Demo1 { public static void getCompanyName(Student student) { Optional<Student> studentOptional = Optional.ofNullable(student); if (studentOptional.isPresent()) { String value1 = studentOptional.flatMap(Student::getJob).fla tMap(Job::getCompany).map(Company::getName). orElse(get("a")); String value2 = studentOptional.flatMap(Student::getJob).fla tMap(Job::getCompany).map(Company::getName). orElseGet(()->get("b")); System.out.println("a: "+value1); System.out.println("b: "+value2); } } public static String get(String name) { System.out.println(name + "执行了方 法"); return "exec"; } public static void main(String[] args) { Company company = new Company(); company.setName("oldlu"); Optional<Company> companyOptional = Optional.of(company); Job job = new Job(); job.setName("pm"); job.setCompany(companyOptional); Optional<Job> jobOptional = Optional.of(job); Student s1 = new Student(); s1.setName("张三"); s1.setJob(jobOptional); getCompanyName(s1); } }
执行结果如下:
a执行了方法 a: oldlu b: oldlu