今天讲解一下java8的Optional类:
以前只知道Optional类是用来解决空指针异常的,并且只知道isPresent()方法。
简单的看一段代码:
@Override
public AdminInfo update(AdminInfo adminInfo) {
/**
* 如果是java8这么写就会报错,说需要使用Optional类,也就是下面这种写法
*/
//Admin admin = adminRepository.findById(adminInfo.getId());
/*if(admin != null) {
//....继续操作admin的逻辑
}*/
Optional<Admin> admin = adminRepository.findById(adminInfo.getId());
}
在简单的了解了Optional类之后,我有很长一段时间是这么写代码的:(笑死自己,貌似还不如上面的简便)
@Override
public AdminInfo update(AdminInfo adminInfo) {
Optional<Admin> admin = adminRepository.findById(adminInfo.getId());
/**
* 只是知道isPresent()方法是判断是否为空的admin.isPresent() == true 就相当于不为空admin != null
* 并且之后操作不为空的admin要用get()来获得
*/
if(admin.isPresent()) {
BeanUtils.copyProperties(adminInfo, admin.get());
createRoleAdmin(adminInfo, admin.get());
return adminInfo;
}else{
return null;
}
}
深入学习Optional之后才知道上面的代码应该这样写:(推荐写法)
@Override
public AdminInfo update(AdminInfo adminInfo) {
Optional<Admin> admin = adminRepository.findById(adminInfo.getId());
/**
* java8 Optional类的使用
*/
AdminInfo ai = admin.map(e -> {
BeanUtils.copyProperties(adminInfo, e);
createRoleAdmin(adminInfo, e);
return adminInfo;
}).orElse(null);
return ai;
}
后来过了段时间,有深入了解学习了一下Optional类,总结使用方法以下几点:
-
创建Optional容器有两种方式
1 调用ofNullable()方法,传入的对象可以为null
2 调用of()方法,传入的对象不可以为null,否则抛出NullPointerException
看下面代码:
@Slf4j
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.setAge(11);
person.setName("yq");
/**
* 调用方法传入null参数
*/
test(null);
}
public static void test(Person p){
/**
* 使用传进来的参数Person类创建一个Optional容器对象
* Optional.ofNullable()可接收null
* Optional.of()不可接收null
*/
Optional<Person> op = Optional.ofNullable(p);
/**
* 接受的参数不能为null否则空指针
* Exception in thread "main" java.lang.NullPointerException
*/
Optional<Person> op1 = Optional.of(p);
}
}
@Data
class Person{
private String name;
private int age;
}
-
Optional容器简单的方法
之前就是只了解了这三个基本方法就擅自改进代码上边我说笑死自己的代码
// 得到容器中的对象,如果为null就抛出异常
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
// 判断容器中的对象是否为null
public boolean isPresent() {
return value != null;
}
// 如果容器中的对象存在,则返回。否则返回传递进来的参数
public T orElse(T other) {
return value != null ? value : other;
}
-
ifPresent(Consumer<? super T> consumer)方法
我们来直接看代码的用法:
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.setAge(11);
person.setName("yq");
/**
* 调用方法传入person对象
*/
test(person);
}
public static void test(Person p){
Optional<Person> op = Optional.ofNullable(p);
/**
* 如果存在person则打印出来(推荐使用)
*/
op.ifPresent(e -> System.out.println(e));
/**
* java8方法引用的写法,也是存在person则打印出来(推荐使用)
*/
op.ifPresent(System.out::println);
/**
* java8之前写法
*
*/
if (p != null) {
System.out.println(p);
}
}
}
@Data
class Person{
private String name;
private int age;
}
-
orElseGet和orElseThrow方法
直接看代码用法:
@Slf4j
public class Test {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setAge(11);
person.setName("yq");
/**
* 调用方法传入person对象
*/
test(person);
}
public static void test(Person p) throws Exception {
Optional<Person> op = Optional.ofNullable(p);
/**
* 如果存在则直接返回对象,不存在则new 一个新的对象
*/
Person person = op.orElseGet(() -> new Person());
log.info("----" + person);
/**
* 如果存在直接返回对象,不存在则抛出异常
*/
Person person1 = op.orElseThrow(() -> new Exception("不存在"));
log.info("*****" + person1);
}
}
@Data
class Person{
private String name;
private int age;
}
-
filter方法
直接看源码:
// 如果容器中的对象存在,并且符合过滤条件,返回装载对象的Optional容器,否则返回一个空的Optional容器
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
// 接口
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
返回Optional对象我们就可以实现链式调用了!
例子:
public static void test(Person p) {
Optional<Person> optional = Optional.ofNullable(p);
// 如果容器中的对象存在,并且符合过滤条件,返回装载对象的Optional容器,否则返回一个空的Optional容器
optional.filter(e -> "Java3y".equals(e.getName()));
}
-
map方法
直接看代码使用:
public static void test(Person p) {
Optional<Person> optional = Optional.ofNullable(p);
// 如果容器的对象存在,则对其执行调用mapping函数得到返回值。
//然后创建包含mapping返回值的Optional,否则返回空Optional。
optional.map(e -> e.getName()).orElse(null);
}
// 上面一句代码对应着java8之前的老写法:
public String test(Person p) {
if (p != null) {
return p.getName();
}else{
return null;
}
}
- java8的forEach优雅的遍历List和Map
public static void main(String[] args) throws Exception {
List<Person> list = new ArrayList<>();
list.add(new Person("yq", 11));
list.add(new Person("11", 11));
list.add(new Person("12", 11));
/**
* java8遍历
*/
list.forEach(System.out::println);
list.forEach(e -> System.out.println(e));
/**
* java8之前遍历
*/
for (Person p : list) {
System.out.println(p);
}
Map<String,Object> map = new HashMap<>();
map.put("name", "yq");
map.put("age", 11);
/**
* java8遍历
*/
map.forEach((key, value) -> System.out.println("key = " + key + ",value = " + value));
/**
* java8之前遍历
*/
for (String key : map.keySet()) {
String value = map.get(key).toString();
System.out.println("key = " + key + ",value = " + value);
}
}
- java8 Optional的优雅使用方法
/**
* java8 Optional的优雅使用方法
* @param p
* @return
* @throws Exception
*/
public static String test(Person p) throws Exception {
/**
* 以前的写法
*/
if(p != null){
String name = p.getName();
if(name != null){
return name.toUpperCase();
}else{
return null;
}
}else{
return null;
}
}
public static String test1(Person p) throws Exception {
Optional<Person> op = Optional.ofNullable(p);
/**
* java8的写法更加优雅
*/
return op.map(e -> e.getName())
.map(s -> s.toUpperCase())
.orElse(null);
}
网友评论