Optional
package cn.anzhongwei.lean.demo.optional;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Optional;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private Integer age;
private Address address;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Optional<String> optionalGetName() {
return Optional.ofNullable(this.name);
}
}
package cn.anzhongwei.lean.demo.optional;
import lombok.Data;
@Data
public class Address {
private String city;
private String addInfo;
}
package cn.anzhongwei.lean.demo.optional;
import org.junit.Test;
import java.util.*;
import java.util.stream.Collectors;
public class OptionalTest {
/**
* Optional(T value),empty(),of(T value),ofNullable(T value)
* Optional(T value) 是private的属于内部方法
*/
@Test
public void test1() {
//of(T value) 是实际上调用了Optional(T value) 而其内部的requireNonNull方法源码中判断value==null时会抛出空指针异常
//在开发中如果不想隐藏空指针异常时 使用of函数, 不过这种情况几乎不用
//Optional<Person> p1 = Optional.of(null);
//所以如果要创建一个value为null的Optional对象则应该使用 empty()
Optional<Person> pnull = Optional.empty();
//而ofNullable(T value) 则是一个三元表达式 return value == null ? empty() : of(value);
Optional<Person> p0 = Optional.ofNullable(null);
Optional<Person> p1 = Optional.ofNullable(new Person("zhangs", 20));
}
/**
* orElse(T other),orElseGet(Supplier other)和orElseThrow(Supplier exceptionSupplier)
* 这三个函数放一组进行记忆,都是在构造函数传入的value值为null时,进行调用的。
* orElse 和 orElseGet 没区别 可以认为时完全一样的代码
*
* orElseThrow 则会当value为空时抛出一个自定义异常
*/
@Test
public void test2() {
Person p = null;
//当p值不为null时,orElse函数依然会执行createUser()方法
p = Optional.ofNullable(p).orElse(new Person("zhangsan", 20));
System.out.println("调用orElse 当p为null时:"+p);
//而当p不为空,则相当于使用get()方法
p = Optional.ofNullable(p).orElse(new Person("王五", 60));
System.out.println("调用orElse 此时p不为null时:"+p);
//
p = null;
//重新赋值p=null
System.out.println("重新赋值p=:"+p);
p = Optional.ofNullable(p).orElseGet(() -> new Person("lisi", 30));
System.out.println("orElseGet 当p为null时:"+p);
p = Optional.ofNullable(p).orElseGet(() -> new Person("zhaoliu", 34));
System.out.println("orElseGet 此时p不为null时:"+p);
}
@Test
public void testOrElseThrow() {
Person p = new Person("lisi", 30);
p = Optional.ofNullable(p).orElseThrow(()-> new RuntimeException("用户不存在"));
System.out.println("orElseThrow 此时p不为null时:"+p);
p = null;
p = Optional.ofNullable(p).orElseThrow(()-> new RuntimeException("用户不存在"));
}
/**
* map(Function mapper)和flatMap(Function> mapper)
* 这两个函数做的是转换值的操作
*/
@Test
public void test3() {
Person p = new Person("lisi", 30);
String name = Optional.ofNullable(p).map( person -> person.getName()).get();
System.out.println("name="+name);
String optionalName = Optional.ofNullable(p).flatMap(person -> person.optionalGetName()).get();
System.out.println("optionalName="+optionalName);
}
/**
* isPresent()和ifPresent(Consumer consumer)
* isPresent即判断value值是否为空,而ifPresent就是在value值不为空时,做一些操作。
*/
@Test
public void test4() {
Person p = null;
Optional.ofNullable(p).ifPresent(person -> {
});
}
/**
* filter(Predicate predicate)
*/
@Test
public void test5() {
Person p = null;
//如果 p.name 长度小于6则返回, 否则返回EMPTY
Optional<Person> p1 = Optional.ofNullable(p).filter(u -> u.getName().length()<6);
}
/**
* 实战写法1
*/
public String getCity(Person person) throws Exception{
if(person!=null){
if(person.getAddress()!=null){
Address address = person.getAddress();
if(address.getCity()!=null){
return address.getCity();
}
}
}
throw new RuntimeException("取值错误");
}
public String getCity2(Person person) throws Exception{
return Optional.ofNullable(person)
.map(u-> u.getAddress())
.map(a->a.getCity())
.orElseThrow(()->new Exception("取值错误"));
}
/**
* 实战写法2
*/
public void dosomething(Person person) {
if (Objects.nonNull(person)) {
//......
}
Optional.ofNullable(person).ifPresent(person1 -> {
//......
});
}
/**
* 实战写法3
*/
public Person getUser1(Person user){
if(user!=null){
String name = user.getName();
if(!"zhangsan".equals(name)){
user = new Person();
user.setName("zhangsan");
}
}else{
user = new Person();
user.setName("zhangsan");
}
return user;
}
public Person getUser2(Person user) {
return Optional.ofNullable(user)
.filter(u->"zhangsan".equals(u.getName()))
.orElseGet(()-> {
Person user1 = new Person();
user1.setName("zhangsan");
return user1;
});
}
public Person getUser3(Person user){
if(user!=null){
String name = user.getName();
if(!"zhangsan".equals(name)){
user.setName("zhangsan");
}
}else{
user = new Person();
user.setName("zhangsan");
}
return user;
}
public Person getUser4(Person user) {
//这个逻辑一般来说不会这么写, 大多数情况下都是不为空且不为zhangsan时, 将name赋值成zhangsan,而不是重新实例化
return Optional.ofNullable(user)
.filter(u->"zhangsan".equals(u.getName()))
.orElseGet(()-> {
if (Objects.nonNull(user)) {
user.setName("zhangsan");
return user;
} else {
Person user1 = new Person();
user1.setName("zhangsan");
return user1;
}
});
}
@Test
public void test6() {
//getUser1 和 getUser2 只要name不等于 zhangsan, 就重新初始化
Person p = new Person("wangwu", 26);
Person p1 = getUser1(p);
System.out.println("p1:"+p1);
p = new Person("lisi", 23);
Person p2 = getUser2(p);
System.out.println("p2:"+p2);
//getUser3 和 getUser4 name不等于 zhangsan, 只改变name=张三, 其他内容不变
p = new Person("zhaosi", 26);
Person p3 = getUser3(p);
System.out.println("p3:"+p3);
p = new Person("liuqi", 26);
Person p4 = getUser4(p);
System.out.println("p4:"+p4);
}
@Test
public void test7() {
List<Person> personList = new ArrayList<>();
Person p1 = new Person("zhangsan", 22);personList.add(p1);
Person p2 = new Person("zhaosi", 29);personList.add(p2);
Person p3 = new Person("wangwu", 22);personList.add(p3);
Person p4 = new Person("lisen", 35);personList.add(p4);
Person p5 = new Person("liuming", 248);personList.add(p5);
Optional<Person> personOptional = personList.stream().filter(p -> p.getAge() > 22).findFirst();
Person pp1 = personOptional.orElseGet(() -> personList.get(0));
System.out.println(pp1);
Person pp2 = personOptional.orElse(null);
System.out.println(pp2);
List<Person> personList2 = Optional.ofNullable(personList).orElseGet(ArrayList::new);
System.out.println(personList2);
Map<String, List<Person>> pMap = new HashMap<>();
// List<Person> personList3 = Optional.ofNullable(pMap.get("随便写"))
// //这种写法主要为了后面stream()的流式处理方式不会有空指针
// //这样会空指针
// .get()
// .stream().collect(Collectors.toList());
// System.out.println(personList3);
List<Person> personList4 = Optional.ofNullable(pMap.get("随便写"))
//这种写法主要为了后面stream()的流式处理方式不会有空指针
.orElseGet(ArrayList::new)
.stream().collect(Collectors.toList());
System.out.println(personList4);
}
}