初始化
Optional提供了三个初始化方法:
@SpringBootTest
public class OptionalTest {
@Test
public void testOptional() {
Optional.empty();
Optional.ofNullable(null);
Optional.of(null);
}
}
empty返回一个空的Optional对象。
of遇到空会报错,但是使用Optional的目的就是防止空指针,所以一般使用ofNullable较多。
ifPresent
ifPresent——如果存在则xxx
public void testOptional() {
Student student = new Student();
student.setName("feng");
student.setAge(18);
Optional.of(student);
// 普通做法
if(student != null){
System.out.println(student.getName());
}
// Optional普通用法
Optional<Student> optional = Optional.ofNullable(student);
if(optional.isPresent()){
Student student1 = optional.get();
System.out.println(student1.getName());
}
// 正确用法
optional.map(new Function<Student, String>() {
@Override
public String apply(Student student) {
return student.getName();
}
}).ifPresent(System.out::println);
// 简化
optional.map(Student::getName).ifPresent(System.out::println);
}
orElse和orElseGet
如果没有对象,则调用一个创建对象的方法。
orElse类似于饿汉式,如果当前对象不为空就使用当前的对象,如果为空则调用方法去创建一个新对象。
orElseGet类似于懒汉式,只有当前对象为空才会去调用,通常使用orElseGet较多。
当前对象不为空:
public void testOptional() {
Student student = new Student();
student.setName("feng");
student.setAge(18);
Optional<Student> optional = Optional.ofNullable(student);
Student student1 = optional.orElse(createStudent());
// orElseGet接收一个Suppilier,一个匿名内部类,调用get方法处理逻辑
Student student2 = optional.orElseGet(new Supplier<Student>() {
@Override
public Student get() {
return createStudent();
}
});
}
private Student createStudent(){
System.out.println("create student");
return new Student();
}
当前对象为空:
public void testOptional() {
Student student = null;
Optional<Student> optional = Optional.ofNullable(student);
Student student1 = optional.orElse(createStudent());
// orElseGet接收一个Suppilier,一个匿名内部类,调用get方法处理逻辑
Student student2 = optional.orElseGet(new Supplier<Student>() {
@Override
public Student get() {
return createStudent();
}
});
}
private Student createStudent(){
System.out.println("create student");
return new Student();
}
过滤
public void testOptional() {
Student student = new Student();
student.setName("feng");
student.setAge(18);
Optional<Student> optional = Optional.ofNullable(student);
optional.filter(student1 -> student1.getAge() > 1).ifPresent(student1 -> System.out.println(student1.getAge()));
}
map和flatMap
Optional
是Java中用于处理可能包含或不包含值的容器类。Optional
提供了一些方法来对这些值进行操作,其中包括map
和flatMap
。
Optional.map
:map
方法用于在Optional
包含值的情况下,对其进行转换或操作。- 如果
Optional
包含一个值,map
会将这个值传递给提供的函数,并返回一个包含转换结果的新Optional
。 - 如果
Optional
为空,map
不执行任何操作,直接返回一个空Optional
。 map
的签名如下:<U> Optional<U> map(Function<? super T, ? extends U> mapper)
Optional<String> optional = Optional.of("Hello");
Optional<Integer> lengthOptional = optional.map(s -> s.length());
在上面的例子中,optional
包含一个字符串值"Hello",map
方法将字符串长度计算并返回一个新的Optional
包含计算结果,即一个整数。
Optional.flatMap
:flatMap
方法用于在Optional
包含值的情况下,进行一种扁平映射,它期望传入的函数返回另一个Optional
。- 如果
Optional
包含一个值,flatMap
会将这个值传递给提供的函数,该函数返回一个Optional
,然后flatMap
返回这个新的Optional
。 - 如果
Optional
为空,flatMap
不执行任何操作,直接返回一个空Optional
。 flatMap
的签名如下:<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
Optional<String> optional = Optional.of("Hello");
Optional<Integer> lengthOptional = optional.flatMap(s -> Optional.of(s.length()));
在上面的例子中,optional
包含一个字符串值"Hello",flatMap
方法将字符串长度计算并返回一个新的Optional
包含计算结果,即一个整数。注意,flatMap
函数返回的是Optional<Integer>
,而不是Optional<Optional<Integer>>
,这是因为flatMap
会自动将嵌套的Optional
展平为单层。
总结:
map
用于对包含的值进行转换,并返回新的Optional
。flatMap
用于对包含的值进行扁平映射,并返回一个新的Optional
,通常用于解决嵌套Optional
的问题。
整体使用
// 普通
public void before8(List<Student> Students) {
for (Student student:Students) {
if (student != null){
if (student.getAge() > 18){
Integer score = student.getScore();
if (score != null && score > 80){
System.out.println(student.getName());
}
}
}
}
}
//1
public void after8(List<Student> students) {
students.stream()
.filter(Objects::nonNull) // 过滤掉空的学生对象
.filter(student -> student.getAge() > 18) // 按年龄过滤
.map(Student::getScore) // 映射为分数
.filter(score -> score != null && score > 80) // 按分数过滤
.map(Student::getName) // 映射为姓名
.ifPresent(System.out::println); // 如果存在姓名则打印
}
public void after8(List<Student> Students) {
for (Student student:Students) {
Optional<Student> studentOptional = Optional.of(student);
// 2
Integer sorce = studentOptional
.filter(s -> s.getAge() > 18)
.map(Student::getScore)
.orElse(0);//.orElse(0)返回一个默认值,防止控空指针
if (sorce > 80){
System.out.println(student.getName());
}
// 3
String name = studentOptional
.filter(s -> s.getAge() >= 18)
.filter(s -> s.getScore() > 80)
.map(Student::getName)
.orElse("wu");//.orElse(0)返回一个默认值,防止控空指针
System.out.println(name);
}
}