详解JAVA中的OPTIONAL

详解JAVA中的Optional

Java中的Optional是Java8中新增的类,用于解决空指针异常。Optional类通过包装对象的形式,判断对象是否为空,从而避免空指针异常。

Optional基本概念

Optional的创建

Optional的创建有两种方法:empty()和of(T value)。

当要创建一个空的Optional对象时,可以使用empty方法:

Optional<String> emptyOptional = Optional.empty(); // 创建一个空的Optional对象

当要创建一个非空的Optional对象时,可以使用of方法:

String str = "Hello";
Optional<String> nonEmptyOptional = Optional.of(str); // 创建一个非空的Optional对象

如果使用of方法时,传入的对象为null,则会抛出NullPointerException。

判断Optional是否为空

Optional类提供了isPresent()和isEmpty()两个方法来判断Optional是否为空。

Optional<String> strOptional = Optional.ofNullable("Hello");
if (strOptional.isPresent()) {
    System.out.println(strOptional.get());
}

Optional<String> emptyOptional = Optional.empty();
if (emptyOptional.isEmpty()) {
    System.out.println("This Optional is empty.");
}

获取Optional中的值

Optional类提供了get()方法来获取Optional中的值。如果Optional中的对象为空,调用get()方法会抛出NoSuchElementException。

Optional<String> strOptional = Optional.ofNullable("Hello");
if (strOptional.isPresent()) {
    System.out.println(strOptional.get());
}

Optional<String> emptyOptional = Optional.empty();
try {
    emptyOptional.get();
} catch (NoSuchElementException e) {
    System.out.println("This Optional is empty.");
}

设置默认值

Optional类提供了orElse(T other)和orElseGet(Supplier<? extends T> other)两个方法,用于在Optional为空时返回默认值。

orElse方法返回一个默认值,如果Optional不为空,返回Optional的值;orElseGet方法根据传入的Supplier返回一个默认值。

Optional<String> strOptional = Optional.empty();
String result = strOptional.orElse("Default value");
System.out.println(result); // 输出:Default value

Optional<String> nonEmptyOptional = Optional.of("Non-empty value");
String result2 = nonEmptyOptional.orElse("Default value");
System.out.println(result2); // 输出:Non-empty value

orElse方法在Optional为空时,会返回指定的默认值;orElseGet方法在Optional为空时,会调用Supplier提供默认值。与orElse方法相比,orElseGet方法更适合于获取成本较高的默认值。

Optional<String> strOptional = Optional.empty();
String expensiveDefault = expensiveComputation(); // 模拟计算成本较高的默认值
String result = strOptional.orElseGet(() -> expensiveDefault);
System.out.println(result); // 输出计算得到的默认值

抛出异常

Optional类提供了orElseThrow()方法,用于在Optional为空时,抛出指定的异常。

Optional<String> strOptional = Optional.empty();
strOptional.orElseThrow(IllegalArgumentException::new); // 抛出IllegalArgumentException异常

Optional在业务中的使用

示例一:使用Optional避免空指针异常

假设有一个Person类包含了name和address属性,现在需要根据姓名获取该Person所在的国家。

public class Person {
    private String name;
    private Address address;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

public class Address {
    private String country;

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
}

在传统方式中,如果要获取该Person所在的国家,需要先判断Person和Address对象是否为空,如下所示:

public String getCountryByName(String name) {
    Person person = findPersonByName(name);
    if (person != null) {
        Address address = person.getAddress();
        if (address != null) {
            return address.getCountry();
        }
    }
    return null;
}

如果使用Optional来改写上面的代码,代码更加简洁和安全:

public String getCountryByName(String name) {
    Optional<Person> optionalPerson = Optional.ofNullable(findPersonByName(name));
    return optionalPerson.flatMap(person -> Optional.ofNullable(person.getAddress()))
                         .map(Address::getCountry)
                         .orElse("Unknown");
}

示例二:使用Optional实现接口参数的可选性

假设有一个接口,该接口有一个必传参数和一个可选参数,为了支持可选参数,可以将可选参数包装成Optional类型。

public interface ProductService {
    int getPrice(String productName);
    int getPrice(String productName, int discount);
}

public class ProductServiceImpl implements ProductService {

    private Map<String, Integer> products = new HashMap<>();

    ProductServiceImpl() {
        products.put("phone", 1000);
        products.put("computer", 2000);
        products.put("camera", 3000);
    }

    @Override
    public int getPrice(String productName) {
        return products.getOrDefault(productName, 0);
    }

    @Override
    public int getPrice(String productName, int discount) {
        return Optional.ofNullable(products.get(productName))
                       .map(price -> price * discount / 100)
                       .orElse(products.getOrDefault(productName, 0));
    }
}

在实现getPrice方法时,使用了Optional包装可选参数discount,这样就可以在方法内部判断是否有折扣参数传入,来返回相应的价格。

最佳实践

  1. Optional不是语言特性,而是库特性,因此使用Optional时,尽量避免在类的成员变量中存储Optional类型。在需要返回Optional类型的方法中使用Optional就足够了。
  2. 将Optional看作是一种特殊的容器类型,用来存储可能为空的值。
  3. 可以使用orElse方法和orElseGet方法设置默认值,但应尽量避免调用get()方法,而是使用orElse、orElseGet等方法来获取Optional中的值。
  4. 对于集合类型,可以使用stream()和filter()方法来过滤null值。

结论

Optional类非常适合于编写的API,特别是在公开API时,Optional可以明确属性是否可能为空,从而能够更好地告知使用者。

然而,在很多情况下,使用Optional并不一定会让代码更加优雅,更加简单和清晰。因此,在使用Optional时,需要慎重考虑。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JAVA中的OPTIONAL - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 解决ajax异步请求返回的是字符串问题

    在Web开发中,我们经常使用Ajax异步请求来获取数据。然而,有时我们会遇到返回的数据是字符串的问题。在本文中,我们将详细讲解如何解决这个问题,并提供两个示例来说明这个过程。 问题描述 当我们使用Ajax异步请求获取数据时,有时会遇到返回的数据是字符串的问题。例如,我们可能会编写以下代码: $.ajax({ url: "/getData"…

    Java 2023年5月18日
    00
  • Spring Security实现分布式系统授权方案详解

    Spring Security实现分布式系统授权方案详解 简介 Spring Security是一个基于Spring的安全框架,提供了一套全面的安全服务,支持Web访问控制、安全认证、权限管理、API授权等。在分布式系统中,如何对服务进行安全认证和权限控制变得十分重要。本文将介绍如何使用Spring Security实现分布式系统的授权方案。 实现步骤 1.…

    Java 2023年6月3日
    00
  • 简单了解Java程序运行整体流程

    下面我将为你详细讲解“简单了解Java程序运行整体流程”的完整攻略。 1. Java程序运行流程 Java程序的运行可以分为三个主要步骤:编写代码、编译代码和运行程序。下面我将为你详细讲解这三个步骤: 1.1 编写代码 要编写Java程序,需要使用Java编程语言。Java是一种高级编程语言,非常易学易用。在编写Java程序时,可以使用任何文本编辑器。Jav…

    Java 2023年5月23日
    00
  • 浅谈Java自定义注解相关知识

    浅谈Java自定义注解相关知识 什么是Java注解 Java注解(Annotation),是Java SE 5.0中新增的一个特性,也是Java语言中一个重要的元编程工具。注解是对程序代码进行一些特殊标记的一种形式化语言机制,用于在源代码中嵌入元数据信息,以及为编译器、虚拟机、运行期系统等软件提供提示和解释性信息,以达到代码分析、配置文件生成,甚至是程序编译…

    Java 2023年5月27日
    00
  • Java 实战项目锤炼之在线美食网站系统的实现流程

    Java 实战项目锤炼之在线美食网站系统的实现流程 1. 确定需求 在项目启动前,首先要仔细理解用户的需求。针对在线美食网站系统,我们需要明确以下问题: 网站需要提供哪些功能,例如用户注册、登录、浏览餐厅、下单、支付等 网站需要支持哪些业务特性,例如搜索、推荐、评价等 网站需要支撑多少用户量,需要考虑如何做好服务器部署和负载均衡 网站的安全性需要考虑哪些问题…

    Java 2023年5月19日
    00
  • Java CAS机制详解

    Java CAS机制详解 什么是CAS机制 CAS(Compare And Swap),即比较并替换,是一种并发控制方式。它的思想是:当多个线程尝试同时更新某一个内存地址时,只有其中一个线程能更新成功,而其余的线程都需要等待。这种方式在并发编程中是很常见的。 CAS机制是通过硬件保证操作的原子性,来避免线程安全问题。 CAS操作的原理 CAS机制需要涉及到三…

    Java 2023年5月26日
    00
  • 浅析Java Web错误/异常处理页面

    下面是“浅析Java Web错误/异常处理页面”的完整攻略: 1. 理解错误/异常处理页面 当 Java Web 应用程序出现错误或异常时,系统会自动跳转到错误/异常处理页面,这个页面通常包含错误/异常信息,以及一些对用户或系统管理员进行解释的说明。 常见的错误/异常处理页面有两种类型: 系统默认的错误/异常处理页面 自定义的错误/异常处理页面 系统默认的错…

    Java 2023年5月27日
    00
  • Javascript与flash交互通信基础教程

    “Javascript与Flash交互通信基础教程”指的是在一个HTML页面中,使用Javascript与Flash技术实现相互通信,从而达到一些动态效果或交互功能的目的。具体的实现方式可以通过swfobject.js插件实现,以下是详细的攻略: 步骤一:创建Flash文件 首先需要使用Flash软件创建Flash文件,并且为Flash文件命名。在编写Fla…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部