Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Gestión de Valores con la Clase Optional | Operaciones Terminales en la Stream API
Stream API

bookGestión de Valores con la Clase Optional

En Java, las variables que almacenan objetos pueden contener un valor null. Esto a menudo conduce a un NullPointerException si null no se maneja correctamente. Estos errores hacen que el código sea menos fiable y más difícil de mantener. Aquí es donde entra en juego Optional.

Piénsalo como una caja: puede contener un valor o puede estar vacía. En lugar de utilizar sentencias if para comprobar si es null, se trabaja con esta "caja" y se emplean métodos convenientes para recuperar el valor de forma segura si existe.

Sintaxis y uso de Optional

El objetivo principal de Optional es evitar el NullPointerException reemplazando las comprobaciones estándar if (value != null) por métodos más legibles.

Existen tres formas de crear un Optional:

  • Optional.empty() – crea un Optional vacío sin valor;
  • Optional.of(value) – envuelve el objeto proporcionado, pero solo si se garantiza que no es null;
  • Optional.ofNullable(value) – envuelve el objeto, incluso si es null, creando un Optional poblado o uno vacío.
Main.java

Main.java

copy
123456789101112131415
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> emptyOpt = Optional.empty(); Optional<String> optWithValue = Optional.of("Laptop"); Optional<String> optNullable = Optional.ofNullable(null); System.out.println("Empty Optional: " + emptyOpt); System.out.println("Optional with value: " + optWithValue); System.out.println("Optional with null: " + optNullable); } }

Si se pasa null a Optional.of(value), el programa lanzará una NullPointerException, por lo que siempre se debe utilizar ofNullable() para valores que pueden estar vacíos.

Recuperación de valores desde Optional

Para extraer un valor de un Optional, se puede utilizar el método get().

Main.java

Main.java

copy
12345678910
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> optWithValue = Optional.of("Laptop"); System.out.println("Final string: " + optWithValue.get()); } }

Aquí, get() devuelve el objeto real almacenado dentro de Optional. Sin embargo, si el Optional está vacío (contiene null), llamar a get() lanzará una NoSuchElementException.

Comprobación de un valor

Al trabajar con Optional, es necesario comprobar si contiene un valor. Una forma de hacerlo es mediante isPresent(), que devuelve true si hay un valor presente. Sin embargo, a menudo se prefiere ifPresent(), ya que ejecuta una expresión lambda proporcionada solo si el valor existe.

Main.java

Main.java

copy
123456789101112131415161718
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); if (productOpt.isPresent()) { System.out.println("Product found: " + productOpt.get()); } else { System.out.println("Product not found."); } // A more concise approach productOpt.ifPresent(product -> System.out.println("Product: " + product)); } }

En el primer ejemplo, se verifica manualmente la presencia de un valor utilizando isPresent() antes de llamar a get(). El segundo ejemplo elimina la necesidad de una sentencia if mediante el uso de una expresión lambda que se ejecuta solo si el producto está presente.

Proporcionar un valor predeterminado

En ocasiones, cuando falta un valor, es recomendable devolver una alternativa. Esto se puede lograr con orElse(), que proporciona un valor de respaldo. Si la generación del valor de respaldo requiere cálculo, orElseGet() resulta más eficiente, ya que solo ejecuta la función cuando es necesario.

Main.java

Main.java

copy
123456789101112131415
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); String product = productOpt.orElse("Default product"); System.out.println("Selected product: " + product); String productLazy = productOpt.orElseGet(() -> "Fallback product"); System.out.println("Selected product (lazy): " + productLazy); } }

La diferencia es que orElse() siempre crea el valor alternativo, incluso si no es necesario, mientras que orElseGet() llama a la función proporcionada solo si Optional está vacío.

Lanzar una excepción si falta el valor

En algunos casos, la ausencia de un valor es un error. En tales situaciones, se puede utilizar orElseThrow() para lanzar una excepción.

Main.java

Main.java

copy
123456789101112
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); String product = productOpt.orElseThrow(() -> new RuntimeException("Product not found")); System.out.println("Product: " + product); } }

Aquí, si el Optional está vacío, el programa lanza una RuntimeException. Esto es útil cuando un valor faltante representa un error crítico.

Transformación de valores

A menudo, un Optional contiene objetos complejos, pero puede que solo sea necesario trabajar con campos específicos. En estos casos, se utiliza map(), que aplica una función dada si hay un valor presente.

Main.java

Main.java

copy
123456789101112
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable("Laptop"); Optional<Integer> nameLengthOpt = productOpt.map(String::length); nameLengthOpt.ifPresent(length -> System.out.println("Product name length: " + length)); } }

Si el Optional está vacío, map() simplemente devuelve Optional.empty(). De lo contrario, aplica String::length y devuelve un Optional<Integer>.

Filtrado de valores

En ocasiones, es necesario conservar un valor solo si cumple con una determinada condición. El método filter() ayuda reteniendo el valor si el predicado proporcionado devuelve true o devolviendo Optional.empty() si no se cumple la condición.

Main.java

Main.java

copy
123456789101112
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.of("Laptop"); Optional<String> filteredProductOpt = productOpt.filter(name -> name.length() > 5); filteredProductOpt.ifPresent(name -> System.out.println("Filtered product: " + name)); } }

Si la longitud de la cadena es mayor que 5, el valor se mantiene; de lo contrario, el Optional queda vacío.

1. ¿Qué sucede si llamas a get() en un Optional vacío?

2. ¿Qué imprimirá este código?

3. ¿Cuál será el resultado del siguiente código?

4. ¿Qué método es el más adecuado para proporcionar un valor predeterminado que solo se calcula cuando es necesario?

question mark

¿Qué sucede si llamas a get() en un Optional vacío?

Select the correct answer

question mark

¿Qué imprimirá este código?

Select the correct answer

question mark

¿Cuál será el resultado del siguiente código?

Select the correct answer

question mark

¿Qué método es el más adecuado para proporcionar un valor predeterminado que solo se calcula cuando es necesario?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 3. Capítulo 5

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Awesome!

Completion rate improved to 2.33

bookGestión de Valores con la Clase Optional

Desliza para mostrar el menú

En Java, las variables que almacenan objetos pueden contener un valor null. Esto a menudo conduce a un NullPointerException si null no se maneja correctamente. Estos errores hacen que el código sea menos fiable y más difícil de mantener. Aquí es donde entra en juego Optional.

Piénsalo como una caja: puede contener un valor o puede estar vacía. En lugar de utilizar sentencias if para comprobar si es null, se trabaja con esta "caja" y se emplean métodos convenientes para recuperar el valor de forma segura si existe.

Sintaxis y uso de Optional

El objetivo principal de Optional es evitar el NullPointerException reemplazando las comprobaciones estándar if (value != null) por métodos más legibles.

Existen tres formas de crear un Optional:

  • Optional.empty() – crea un Optional vacío sin valor;
  • Optional.of(value) – envuelve el objeto proporcionado, pero solo si se garantiza que no es null;
  • Optional.ofNullable(value) – envuelve el objeto, incluso si es null, creando un Optional poblado o uno vacío.
Main.java

Main.java

copy
123456789101112131415
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> emptyOpt = Optional.empty(); Optional<String> optWithValue = Optional.of("Laptop"); Optional<String> optNullable = Optional.ofNullable(null); System.out.println("Empty Optional: " + emptyOpt); System.out.println("Optional with value: " + optWithValue); System.out.println("Optional with null: " + optNullable); } }

Si se pasa null a Optional.of(value), el programa lanzará una NullPointerException, por lo que siempre se debe utilizar ofNullable() para valores que pueden estar vacíos.

Recuperación de valores desde Optional

Para extraer un valor de un Optional, se puede utilizar el método get().

Main.java

Main.java

copy
12345678910
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> optWithValue = Optional.of("Laptop"); System.out.println("Final string: " + optWithValue.get()); } }

Aquí, get() devuelve el objeto real almacenado dentro de Optional. Sin embargo, si el Optional está vacío (contiene null), llamar a get() lanzará una NoSuchElementException.

Comprobación de un valor

Al trabajar con Optional, es necesario comprobar si contiene un valor. Una forma de hacerlo es mediante isPresent(), que devuelve true si hay un valor presente. Sin embargo, a menudo se prefiere ifPresent(), ya que ejecuta una expresión lambda proporcionada solo si el valor existe.

Main.java

Main.java

copy
123456789101112131415161718
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); if (productOpt.isPresent()) { System.out.println("Product found: " + productOpt.get()); } else { System.out.println("Product not found."); } // A more concise approach productOpt.ifPresent(product -> System.out.println("Product: " + product)); } }

En el primer ejemplo, se verifica manualmente la presencia de un valor utilizando isPresent() antes de llamar a get(). El segundo ejemplo elimina la necesidad de una sentencia if mediante el uso de una expresión lambda que se ejecuta solo si el producto está presente.

Proporcionar un valor predeterminado

En ocasiones, cuando falta un valor, es recomendable devolver una alternativa. Esto se puede lograr con orElse(), que proporciona un valor de respaldo. Si la generación del valor de respaldo requiere cálculo, orElseGet() resulta más eficiente, ya que solo ejecuta la función cuando es necesario.

Main.java

Main.java

copy
123456789101112131415
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); String product = productOpt.orElse("Default product"); System.out.println("Selected product: " + product); String productLazy = productOpt.orElseGet(() -> "Fallback product"); System.out.println("Selected product (lazy): " + productLazy); } }

La diferencia es que orElse() siempre crea el valor alternativo, incluso si no es necesario, mientras que orElseGet() llama a la función proporcionada solo si Optional está vacío.

Lanzar una excepción si falta el valor

En algunos casos, la ausencia de un valor es un error. En tales situaciones, se puede utilizar orElseThrow() para lanzar una excepción.

Main.java

Main.java

copy
123456789101112
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); String product = productOpt.orElseThrow(() -> new RuntimeException("Product not found")); System.out.println("Product: " + product); } }

Aquí, si el Optional está vacío, el programa lanza una RuntimeException. Esto es útil cuando un valor faltante representa un error crítico.

Transformación de valores

A menudo, un Optional contiene objetos complejos, pero puede que solo sea necesario trabajar con campos específicos. En estos casos, se utiliza map(), que aplica una función dada si hay un valor presente.

Main.java

Main.java

copy
123456789101112
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable("Laptop"); Optional<Integer> nameLengthOpt = productOpt.map(String::length); nameLengthOpt.ifPresent(length -> System.out.println("Product name length: " + length)); } }

Si el Optional está vacío, map() simplemente devuelve Optional.empty(). De lo contrario, aplica String::length y devuelve un Optional<Integer>.

Filtrado de valores

En ocasiones, es necesario conservar un valor solo si cumple con una determinada condición. El método filter() ayuda reteniendo el valor si el predicado proporcionado devuelve true o devolviendo Optional.empty() si no se cumple la condición.

Main.java

Main.java

copy
123456789101112
package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.of("Laptop"); Optional<String> filteredProductOpt = productOpt.filter(name -> name.length() > 5); filteredProductOpt.ifPresent(name -> System.out.println("Filtered product: " + name)); } }

Si la longitud de la cadena es mayor que 5, el valor se mantiene; de lo contrario, el Optional queda vacío.

1. ¿Qué sucede si llamas a get() en un Optional vacío?

2. ¿Qué imprimirá este código?

3. ¿Cuál será el resultado del siguiente código?

4. ¿Qué método es el más adecuado para proporcionar un valor predeterminado que solo se calcula cuando es necesario?

question mark

¿Qué sucede si llamas a get() en un Optional vacío?

Select the correct answer

question mark

¿Qué imprimirá este código?

Select the correct answer

question mark

¿Cuál será el resultado del siguiente código?

Select the correct answer

question mark

¿Qué método es el más adecuado para proporcionar un valor predeterminado que solo se calcula cuando es necesario?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 3. Capítulo 5
some-alt