Optional介绍
根据Oracle文档,Optional是一个容器对象,可以包含也可以不包含非null值。Optional在Java 8中引入,目的是解决 NullPointerExceptions的问题。本质上,Optional是一个包装器类,其中包含对其他对象的引用。在这种情况下,对象只是指向内存位置的指针,并且也可以指向任何内容。从其它角度看,Optional提供一种类型级解决方案来表示可选值而不是空引用。
在Java 8之前,程序员将返回null而不是Optional。这种方法有一些缺点。一种是没有明确的方法来表示null可能是一个特殊值。相比之下,在API中返回Optional是明确的声明,其中可能没有值。如果我们要确保不会出现空指针异常,则需要对每个引用进行显式的空检查,如下所示,我们都同意这是很多样板。
Java8中,引入了Optional类。它的目的是为了解决Java中频繁的判空操作。
例子
通过一个例子来查看使用Optional的效果。
//例子
@Test
public void liZi(){
int l1 = getLength("admin");
int l2 = getLength1("lisa");
System.out.println(l1);
System.out.println(l2);
}
//普通判断
public static int getLength(String s){
if (s == null) {
return 0;
}
return s.length();
}
//使用Optional判断
public static int getLength1(String s){
return Optional.ofNullable(s).map(String::length).orElse(0);
}
/*输出:
5
4*/
样例1:把集合存到 Optional.ofNullable()中
Set<Long> roomSuspectedPointids = (Set<Long>) jsonRedisTemplate.opsForHash().get(getRoomCacheKey(day), String.valueOf(hotelId));
return Optional.ofNullable(roomSuspectedPointids);
取出来时 返回结果为Optional<Set<Long>>
可以用Set<Long> longs = pointService.findRoomSuspectedByHotelIdandDayInCache(day, hotelId).orElse(new HashSet<>());
样例2:
Optional<String> of = Optional.ofNullable(null);
String lisa = of.orElse("Lisa");
System.out.println(lisa);
//输出:Lisa
构建实例
Optional提供了三个静态方法来构建实例。
of:入参为空则抛异常。
ofNullable:入参可为空。
empty:空的 Optional。
Optional<String> of = Optional.of("admin");
Optional<String> ofNullable = Optional.ofNullable("admin");
Optional<Object> empty = Optional.empty();
/**
* 例子
*/
@Test
public void liZi() {
int l1 = getLength("admin");
int l2 = getLength1("lisa");
System.out.println(l1);
System.out.println(l2);
}
//普通判断
public static int getLength(String s) {
if (s == null) {
return 0;
}
return s.length();
}
//使用Optional判断
public static int getLength1(String s) {
return Optional.ofNullable(s).map(String::length).orElse(0);
}
/*输出:
5
4*/
/**基本API*/
/**
* 1、get
* 获取传入的对象。
* 对象为NULL会抛异常。
*/
@Test
public void get() {
Optional<String> of = Optional.ofNullable("admin");
System.out.println(of.get());
//输出:admin
}
/**
* 2、isPresent
* 判断当前Optional内元素是否存在。
*/
@Test
public void isPresent() {
Optional<String> of = Optional.ofNullable("admin");
System.out.println(of.isPresent());
// 输出:true
}
/**
* 3、ifPresent
* 如果元素不为空,则执行函数。
*/
@Test
public void ifpresent() {
Optional<String> of = Optional.ofNullable("admin");
of.ifPresent(s -> {
System.out.println("element:" + s);
});
//输出:element:admin
}
/**
* 4、orElse
* 如果元素为空,返回默认值,否则返回元素。
*/
@Test
public void orElse() {
Optional<String> of = Optional.ofNullable(null);
String lisa = of.orElse("Lisa");
System.out.println(lisa);
//输出:Lisa
Optional<BigDecimal> of1 = Optional.ofNullable(BigDecimal.ZERO);
BigDecimal lisa1 = of1.orElse(new BigDecimal("520"));
System.out.println(lisa1);
//输出:0
}
/**
* 5、orElseGet
* 如果元素为空,则执行函数,返回函数的返回值,否则返回元值。
*/
@Test
public void orElseGet() {
Optional<String> of = Optional.ofNullable(null);
String lisa = of.orElseGet(() -> {
System.out.println("元素为空,返回Lisa");
return "Lisa";
});
System.out.println(lisa);
// 输出:
// 元素为空,返回Lisa
// Lisa
}
/**
* 6、orElseThrow
* 如果元素为空,则抛出异常,否则返回元素。
*/
@Test
public void orElseThrow() throws Exception {
Optional<String> of = Optional.ofNullable(null);
of.orElseThrow(() -> new Exception("元素为空,抛异常"));
// 输出:
// Exception in thread "main" java.lang.Exception: 元素为空,抛异常
// at com.ch.java8.optional.Client.lambda$main$0(Client.java:27)
// at java.util.Optional.orElseThrow(Optional.java:290)
// at com.ch.java8.optional.Client.main(Client.java:26)
}
/**
* 7、map
* map用于将元素的值进行转换。
*/
@Test
public void map() {
Optional<String> of = Optional.ofNullable("admin");
String s1 = of.map(s -> "123").get();
System.out.println(s1);
// 输出:123
}
/**
* 8、flatMap
* 用法和map类似,区别是:map会将结果封装为Optional,flatmap需要自己封装。
*/
@Test
public void flatMap() {
Optional<String> of = Optional.ofNullable("admin");
String lisa = of.flatMap(s -> Optional.of("Lisa")).get();
System.out.println(lisa);
// 输出:Lisa
}
/**
* 9、filter
* 过滤元素。
*/
@Test
public void filter() {
Optional<String> of = Optional.ofNullable("admin");
boolean present = of.filter(s -> false).isPresent();
System.out.println(present);
//输出:false
List<UserFilter> userList = new ArrayList<>();
UserFilter user1 = UserFilter.builder().id(1).name("ONE").build();
UserFilter user2 = UserFilter.builder().id(2).name("ZERO").build();
UserFilter user3 = UserFilter.builder().id(3).name("TWO").build();
UserFilter user4 = UserFilter.builder().id(4).name("FOUR").build();
UserFilter user5 = UserFilter.builder().id(5).name("ONE").build();
userList.add(user1);userList.add(user2);userList.add(user3);userList.add(user4);userList.add(user5);
System.out.println("筛选前:" + userList);
userList = userList.stream().filter(o -> o.getName().equals("ONE")).collect(Collectors.toList());
System.out.println("筛选后:" + userList);
}
//练手
@Test
public void test01() {
// 1、创建一个包装对象值为空的Optional对象
Optional<String> optEmpty = Optional.empty();
// 2、创建包装对象值非空的Optional对象
Optional<String> optOf = Optional.of("optional");
// 3、创建包装对象值允许为空也可以不为空的Optional对象
Optional<String> optOfNullable1 = Optional.ofNullable(null);
Optional<String> optOfNullable2 = Optional.ofNullable("optional");
if (optOfNullable1.isPresent()) {
//写不为空的逻辑
System.out.println("不为空");
} else {
//写为空的逻辑
optOfNullable1 = Optional.of("11");
optOfNullable1 = Optional.ofNullable("" + BigDecimal.ZERO);
Optional<BigDecimal> zero = optOfNullable1.ofNullable(BigDecimal.ZERO);
System.out.println("为空" + zero);
}
}
//orElse和orElseGet 的区别
@Test
public void testSupplier() {
Optional<String> opt = Optional.of("前端数据");
String x = opt.orElse(getDefaultValue());
System.out.println("---以上为orElse调用,以下为orElseGet调用---");
String y = opt.orElseGet(() -> getDefaultValue());
}
public String getDefaultValue() { //远程方法调用
System.out.println("我被调用了!");
return "我是默认值";