当前位置: 首页 > 后端技术 > Java

Java8特性可选用法详解

时间:2023-04-01 14:21:59 Java

前言NPE(NullPointerException)一直是Java程序员最痛恨的异常。冗长的非空检查使得代码的可读性和优雅性大打折扣。所以在这篇文章中,笔者将详细介绍Java8引入的特性——Optional类,看看它是如何避免空指针异常的。什么是选项?Optional是一个容器对象,它可能包含也可能不包含非空值。如果该值存在,isPresent()将返回true,而get()将返回该值。提供的其他方法取决于包含的值是否存在,例如orElse()(如果值不存在则返回默认值)和ifPresent()(如果值存在则执行一段代码)。这是一个基于价值的课程;在Optional实例上使用身份敏感操作,包括引用相等性(==)、身份哈希码或同步,可能会产生不可预知的结果,应该避免。Optional解决了什么问题?在Java8之前,我们像这样进行对象验证:publicStringgetCity(Useruser){if(user!=null){Addressaddress=user.getAddress();if(address!=null){返回地址。得到城市();}else{返回“北京”;}}else{返回“北京”;}}Java8写法:publicStringgetCity(Useruser){returnOptional.ofNullable(user).map(u->u.getAddress()).map(address->address.getCity()).orElse("北京");}方法详细说明empty说明返回一个空的Optional实例。源代码publicstaticOptionalempty(){@SuppressWarnings("unchecked")Optionalt=(Optional)EMPTY;returnt;}用法Optionalempty=Optional.empty();创建了一个空的Optional对象,如果此时调用了get()方法,NoSuchElementExceptionOptionalempty=Optional.empty();System.out.println(empty.get());//抛出NoSuchElementExceptionof(Tvalue)描述了为非空值创建一个Optional,传入的参数不能为null,否则会抛出NullPointerException。源代码publicstaticOptionalof(Tvalue){returnnewOptional<>(value);}UsageOptionaluserName=Optional.of("userName");如果传入null,则抛出NullPointerExceptionOptionaluserName=Optional.of(null);//抛出NullPointerExceptionofNullable(Tvalue)Description创建一个可为null的Optional,如果为非null,则返回所描述的指定值可选,否则返回一个空的可选。源代码publicstaticOptionalofNullable(Tvalue){返回值==null?empty():of(value);}用法OptionaluserName=Optional.ofNullable("userName");get()描述如果这个值包含在这个Optional中,则返回值,否则抛出异常:NoSuchElementException。源代码publicTget(){if(value==null){thrownewNoSuchElementException("Novaluepresent");}returnvalue;}UsageOptionaluserName=Optional.ofNullable("userName");System.out.println(userName.get());//输出userNameisPresent()说明如果有值,返回true,否则返回假。源码publicbooleanisPresent(){returnvalue!=null;}用法OptionaluserName=Optional.ofNullable("userName");System.out.println(userName.isPresent());//输出trueOptionalempty=Optional.ofNullable(null);System.out.println(empty.isPresent());//输出falseifPresent(Consumerconsumer)description如果value存在,使用value调用consumer,否则不执行任何操作。要理解ifPresent方法,首先需要理解Consumer类。简而言之,Consumer类包含一个抽象方法。这个抽象方法处理传入的值,但不返回值。Java8支持不用接口直接通过lambda表达式传递参数。如果Optional实例有值,则对ifPresent()的调用可以接受接口段或lambda表达式。源代码publicvoidifPresent(Consumerconsumer){if(value!=null)consumer.accept(value);}用法OptionaluserName=Optional.ofNullable("userName");userName.ifPresent((value)->System.out.println(value.length()));//输出8Optionalempty=Optional.ofNullable(null);empty.ifPresent((value)->System.out.println(value.length()));//无输出,此时Optional为空值,不进行任何操作,返回一个Optionalwith来描述值,否则返回一个空的Optional。源代码publicOptionalfilter(Predicatepredicate){Objects.requireNonNull(predicate);如果(!isPresent())返回这个;否则返回predicate.test(value)?this:empty();}用法OptionaluserName=Optional.ofNullable("userName");OptionalfilterUserName1=userName.filter((value)->value.length()>4);System.out.println(filterUserName1.get());//输出userNameOptionalfilterUserName2=userName.filter((value)->value.length()<4);System.out.println(filterUserName2.get()));//抛出NoSuchElementException,因为此时没有找到匹配的值,返回一个空的Optionalmap(Functionmapper)说明如果有值则映射函数被调用以获得返回值。如果返回值不为null,则创建一个包含map返回值的Optional作为map方法的返回值,否则返回一个空的Optional。源代码publicOptionalmap(Functionmapper){Objects.requireNonNull(mapper);如果(!isPresent())返回空();else{returnOptional.ofNullable(mapper.apply(value));}}用法OptionaluserName=Optional.ofNullable("userName");OptionalmapUserName=userName.map((value)->value.toUpperCase(Locale.ROOT));System.out.println(mapUserName.get());//OutputUSERNAMEflatMap(Function>mapper)description如果值存在,则根据Optional中包含的映射方式返回该值,否则返回一个空的Optional。此方法类似于map(Function),但提供的映射器的返回值必须是Optional。如果被调用,flatMap将不会用额外的Optional包装它。源代码publicOptionalflatMap(Function>mapper){Objects.requireNonNull(mapper);如果(!isPresent())返回空();else{returnObjects.requireNonNull(mapper.apply(value));}}UsageOptionaluserName=Optional.ofNullable("userName");OptionalflatMapUserName=userName.flatMap((value)->Optional.of(value.toUpperCase(Locale.ROOT))//返回映射器的值必须是可选的);System.out.println(flatMapUserName.get());//输出USERNAMEorElse(Tother)description如果该值存在,则返回该值,否则返回other。源代码publicTorElse(Tother){返回值!=null?value:other;}UsageOptionaluserName=Optional.ofNullable("userName");System.out.println(userName.orElse("mobile"));//输出userNameOptionalempty=Optional.empty();System.out.println(empty.orElse("mobile"));//输出mobileorElseGet(Supplierother)description如果存在value,返回值,否则触发other,返回调用other的结果.orElseGet与orElse方法类似,区别在于获取的是默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现来生成默认值。源代码publicTorElseGet(Supplierother){returnvalue!=null?value:other.get();}UsageOptionaluserName=Optional.ofNullable("userName");System.out.println(userName.orElseGet(()->"mobile"));//输出userNameOptionalempty=Optional.empty();System.out.println(empty.orElseGet(()->"mobile"));//OutputmobileorElseThrow(SupplierexceptionSupplier)description如果值存在,则返回包含的值,否则抛出Supplier继承的异常源码publicTorElseThrow(SupplierexceptionSupplier)抛出X{if(value!=null){返回值;}else{抛出exceptionSupplier.get();}}用法try{OptionaluserName=Optional.ofNullable("userName");System.out.println(userName.orElseThrow(Exception::new));//输出用户名}catch(Exceptione){e.printStackTrace();}try{Optionalempty=Optional.empty();System.out.println(empty.orElseThrow(Exception::new));}catch(Exceptione){e.printStackTrace();//异常捕获}总结以上就是Optional各个方法的用法介绍,我还是推荐熟练使用,让你的代码变得更优雅