Compartir tecnología

Un artículo para entender Opcional en Java

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Introducción a lo opcional

Opcional es una nueva clase introducida en java8. El principal problema que resuelve es NullPointerException.
Traducción del texto original (traducción de Baidu, mis defectos en inglés): un objeto contenedor, que puede contener o no valores no nulos. isPresent() devolverá verdadero si el valor está presente. Si no hay ningún valor, el objeto se considera vacío y isPresent() devuelve falso.
Se proporcionan métodos adicionales que dependen de la presencia del valor contenido, como orElse() (devuelve el valor predeterminado si el valor no está presente) e ifPresent() (realiza la acción cuando el valor está presente).
Esta es una clase basada en valores; los programadores deben tratar las instancias iguales como intercambiables y no deben usar instancias para la sincronización; de lo contrario, puede ocurrir un comportamiento impredecible. Por ejemplo, la sincronización puede fallar en una versión futura.

La función principal que entiendo aquí es que puedes pasar isPresent() método para ayudar a juzgar el vacío del objeto y luego pasarmap(), orElse()ifPresent() La combinación de otros métodos puede reducir en gran medida el largo juicio en el código.

2. Interfaces de uso común

先介绍一下常用所有的接口;
注意:
	1. 此列表是列出了本人觉得有意义的接口不是全部。
	2. 当前jdk版本为17,其他版本可能会没有一些方法,例如:`or()` 方法在jdk1.9中增加的
  • 1
  • 2
  • 3
  • 4
Nombre de la interfazBreve descripción de la función.
Optional<T> empty()construir un vacíoOptional objeto
Optional<T> of(T value)Construir un no vacíoOptional objeto si为空则报错
Optional<T> ofNullable(T value)construir unOptional ¡Objeto, se permite estar vacío!
T get()Obtenga un valor de objeto genérico, si el valor为空,则报错
boolean isPresent()vacío si nonull Entonces estrue
boolean isEmpty()vacío sinull Entonces estrue
ifPresent(Consumer)Pase un par de funciones de interfaz, cuando los datos不为空Esta función se ejecuta cuando
ifPresentOrElse(Consumer, Runnable) Dos parámetros, el primero se ejecuta cuando no está vacío y el segundo se ejecuta cuando está vacío. Todas son funciones de interfaz.
Optional<T> filterUn filtro para objetos.
Optional<U> map(Function)Método de conversión
Optional<U> flatMap(Function)Método de conversión, comúnmente utilizado con la conversión de varias capas a una capa.
Optional<T> or(Supplier)Al recibir el objeto为空Al crear uno nuevo basado en la función de interfazOptionalobjeto
T orElse(T)Al recibir el objeto为空Obtener un objeto genérico específico cuando
T orElseThrow()不为空 Objeto de devolución,为空 peroNoSuchElementException
T orElseThrow(Supplier)不为空 Objeto de devolución,为空 pero指定异常

2.1 Las interfaces comunes son fáciles de usar

下面是常用接口的一些简单的演示
  • 1

2.1.1 Métodos comunes de creación

// 1. 构建一个空的 Optional 对象没有任何问题
Optional<Object> empty = Optional.empty();

 // 2. 构建一个非空的 Optional 对象没有任何问题
 Optional<Object> aa = Optional.of("123");
 // 3. 构建一个空的 Optional 对象直接报错  ================ 会报错 of不允许为空
 Optional<Object> bb = Optional.of(null);

 // 4. 构建一个空的 Optional 对象没有任何问题
 Optional<Object> cc = Optional.ofNullable(null);

 // 5. 构建一个非空的 Optional 对象没有任何问题
 Optional<Object> dd = Optional.ofNullable("123");

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.1.2 Métodos comunes para obtener valores


Optional<Object> cc = Optional.ofNullable(null);
// 1. 如果为空的时候获取值就会直接报错
Object o = cc.get();
// 2. 如果对象为空,则获取 or 中的 get 方法的值,否则则获取cc的 get 方法中的值
Object o1 = cc.or(() -> Optional.ofNullable("123")).get();
// 3. 如果对象为空,则直接获取的是 123, orElse()中的参数是非空的。 如果对象不为空则直接获取到对象的值
Object o2 = cc.orElse("123");
// 4. 如果对象为空,则获取 or 中的 get 方法的值,否则则获取cc的 get 方法中的值
Object o3 = cc.orElseGet(() -> Optional.ofNullable("123"));

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.1.3 Métodos comunes de juicio

Optional<Object> cc = Optional.ofNullable(null);
// 1. 存在则返回true
boolean present = cc.isPresent();
// 2. 为null返回true
boolean empty = cc.isEmpty();
  • 1
  • 2
  • 3
  • 4
  • 5

2.1.4 Método de operación después del juicio


Optional<Object> cc = Optional.ofNullable(null);
// 1. 如果对象不为空,则执行方法体的内容,否则没有任何操作
cc.ifPresent(item->{
    System.out.println("不为空则执行我"+item);
});

// 2. 如果对象不为空,则执行方法体的内容,否则没有任何操作
cc.ifPresentOrElse(item->{
    System.out.println("不为空则执行我"+item);
},()->{
    System.out.println("为空则执行我");
});

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.2 Introducción al método de mapas

map 方法的使用跟 Stream 中的map方法一样,我的理解这里面的所有的接口方法与 Stream 中重名的用法都是一样的
  • 1

@Data
public static class User{
    private String name;
    private Integer age;
}
@Test
void getMapTest(){

    User user = new User();
    user.setName("123");
    Optional<User> optionalUser = Optional.of(user);
    // 1. 直接获取 user 对象的 name 的值,这里 map 是当用户不为空的时候执行的
    Optional<String> name = optionalUser.map(User::getName);
    System.out.println(name.isEmpty()); // 输出 false

    Optional<User> optionalUser2 = Optional.ofNullable(null);
    // 2. 直接获取 user 对象的 name 的值,这里 map 是当用户不为空的时候执行的
    Optional<String> name2 = optionalUser2.map(User::getName);
    System.out.println(name2.isEmpty()); // 输出 true
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2.2 Otros métodos

Otros metodos:

2.2.1 Método de filtrado

filter : Este método es para filtrar,Optional<Path> p = uris. stream().filter(uri -> !isProcessedYet(uri)).findFirst() .map(Paths::get); Básicamente, nunca lo he usado aquí y parece que no existe ningún escenario de uso.

2.2.2 Método FlatMap

flatMap: Entiendo que este método es una conversión de unboxing: por ejemplo, ponga Stream<Optional<T>> Convertir aOptional<T>

Stream<Optional<T>> os = ....
Stream<T> s = os.flatMap(Optional::stream)
  • 1
  • 2

3. Ejemplos de uso común

TODO 这里后面再不吧,暂时也没有太合适的例子
  • 1

4. Resumen

Optional Introducido en Java 8, proporciona una forma más elegante y segura de manejar valores potencialmente nulos.Principalmente a travésor ,orElse , ifPresent Esperar a que los métodos funcionales determinen elegantemente el espacio vacío y ejecuten la operación después de que no esté vacío, esto puede reducir múltiples capas deif El juicio hace que el código sea elegante, pero las desventajas son函数式 El método reducirá la legibilidad del código.y también es necesarioLambda Se necesita cierta comprensión.