Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

249
Vistas
How does orElseGet work in case of an Optional<List<Entity>>

I have an Optional of List of a class, i.e.: Optional<List<MyEntity>> opListEntity

I needed to map all MyEntity to MyEntityDto when Optional is present. In case Optional is empty, I'll return an empty ArrayList.


Approach 1 (Non-Functional):

Note: myEntityMapper is an object of a mapper class, which maps MyEntity to MyEntityDto.

List<MyEntityDto> res;
if (opListEntity.isPresent()) {
       res = opListEntity.get().stream()
            .map(myEntityMapper::entityToDto)
            .collect(Collectors.toList());
} else {
       res = new ArrayList<>();
}

This approach is fine but IntelliJ suggests to convert it to a functional-style expression. I let IntelliJ do the conversion and this is what I get:

Approach 2 (function expression):

List<MyEntityDto> res = opListEntity.map(myEntities -> myEntities.stream()
            .map(myEntityMapper::entityToDto)
            .collect(Collectors.toList()))
     .orElseGet(ArrayList::new);

What I don't understand is, In approach 2 @ line 1, why is there a map?

Let me explain a bit more. See the 3rd Approach:

Approach 3:

List<CustomerAddressEntity> myEntities = opListEntity
        .orElseGet(ArrayList::new);
List<MyEntityDto> res = myEntities.stream()
        .map(myEntityMapper::entityToDto)
        .collect(Collectors.toList());

Approach 3 works fine, but if I try to convert approach 3 to approach 4, It doesn't work.

Approach 4:

List<MyEntityDto> res = opListEntity.stream()
            .map(myEntityMapper::entityToDto)
            .collect(Collectors.toList()))
     .orElseGet(ArrayList::new);

why approach 4 doesn't work but approach 2 does?
what is the extra map doing in approach 2 @ line 1?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

I think it becomes obvious if you indent the code a bit more to make it somewhat easier to spot:

List<MyEntityDto> res = opListEntity // Optional<List<MyEntity>>
    .map(
        myEntities -> myEntities.stream() // Stream<MyEntity>
            .map(myEntityMapper::entityToDto)  // Stream<MyEntityDto>
            .collect(Collectors.toList()) // List<MyEntityDto>
        )
    .orElseGet(ArrayList::new); // List<MyEntityDto>

That is the Optional (if present) is mapped to the result of transforming the contained list to a stream, mapping the elements and building a collection, or (if empty) to a new empty list.

In your 4th approach opListEntity is of type Optional<List<MyEntity>>. Now it depends on the JDK version you're using. In JDK8 Optional has no stream() method.

List<MyEntityDto> res = opListEntity.stream() // there is no such method in JDK8
    ...

Since JDK9 there is a stream() method but it will of course return Stream<List<MyEntity>> as this is the type of the Optional. But for the mapping to work you'd need Stream<MyEntity>. To get this you could map the returned stream using the flatMap method:

List<MyEntityDto> res = opListEntity.stream() // Stream<List<MyEntity>>
    .flatMap(List::stream) // Stream<MyEntity>
    .map(myEntityMapper::entityToDto)
...
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda