Lejdi Prifti

0 %
Lejdi Prifti
Software Engineer
Web3 Developer
ML Practitioner
  • Residence:
    Albania
  • City:
    Tirana
  • Email:
    info@lejdiprifti.com
English
Italian
French
Spring
React & Angular
Machine Learning
Docker & Kubernetes
AWS & Cloud
Team Player
Communication
Time Management
  • Java, JavaScript, Python
  • AWS, Kubernetes, Azure
  • Bootstrap, Materialize
  • Stylus, Sass, Less
  • Blockchain, Ethereum, Solidity
  • React, React Native, Flutter
  • GIT knowledge
  • Machine Learning, Deep Learning
0

No products in the basket.

Use orElseGet instead of orElse in Optional

15. October 2023

In this short article, the main point I want to describe is to stop using orElse and favor more orElseGet when using Optional in Java.

Optional is a container that can hold either a non-null value or represent the absence of a value.

public class FootballPlayerService {
private List<FootballPlayer> players;

public FootballPlayerService() {
players = new ArrayList<>();
players.add(new FootballPlayer("Lionel Messi", 34));
players.add(new FootballPlayer("Cristiano Ronaldo", 36));
players.add(new FootballPlayer("Neymar Jr.", 29));
}

public Optional<FootballPlayer> findPlayerByName(String name) {
for (FootballPlayer player : players) {
if (player.getName().equalsIgnoreCase(name)) {
return Optional.of(player);
}
}
return Optional.empty();
}
}

In the example, above we return the player if it is found as an Optional , otherwise we return an empty Optional .

public class FootballPlayerService {
private List<FootballPlayer> players;

public FootballPlayerService() {
players = new ArrayList<>();
players.add(new FootballPlayer("Lionel Messi", 34));
players.add(new FootballPlayer("Cristiano Ronaldo", 36));
players.add(new FootballPlayer("Neymar Jr.", 29));
}

public FootballPlayer findPlayerByName(String name) {
Optional<FootballPlayer> optionalPlayer = players.stream()
.filter(player -> player.getName().equalsIgnoreCase(name))
.findFirst();

return optionalPlayer.orElseThrow(() -> new PlayerNotFoundException(name));
}
}

We could write the same function, but this time we return the FootballPlayer object if it is found, and if not, we throw an exception. This really improves the code and makes it more readable, as we leverage also the benefits of the Stream class.

However, sometimes you want to return a default object if the one that you are looking for cannot be found. There are two ways you can do it.

  1. orElse
public class FootballPlayerService {
private List<FootballPlayer> players;

public FootballPlayerService() {
players = new ArrayList<>();
players.add(new FootballPlayer("Lionel Messi", 34));
players.add(new FootballPlayer("Cristiano Ronaldo", 36));
players.add(new FootballPlayer("Neymar Jr.", 29));
}

public FootballPlayer findPlayerByName(String name) {
Optional<FootballPlayer> optionalPlayer = players.stream()
.filter(player -> player.getName().equalsIgnoreCase(name))
.findFirst();

return optionalPlayer.orElse(new FootballPlayer("Neymar Jr.", 29));
}
}

2. orElseGet

public class FootballPlayerService {
private List<FootballPlayer> players;

public FootballPlayerService() {
players = new ArrayList<>();
players.add(new FootballPlayer("Lionel Messi", 34));
players.add(new FootballPlayer("Cristiano Ronaldo", 36));
players.add(new FootballPlayer("Neymar Jr.", 29));
}

public FootballPlayer findPlayerByName(String name) {
Optional<FootballPlayer> optionalPlayer = players.stream()
.filter(player -> player.getName().equalsIgnoreCase(name))
.findFirst();

return optionalPlayer.orElseGet(() ->
new FootballPlayer("Neymar Jr.", 29));
}
}

Difference

The difference between the two is that despite of the condition that optionalPlayer is null or not, the object inside orElse will always be created. In fact, it is created before the conditon is evaluated. However, this is not the case for orElseGet . The object is created only if the optionalPlayeris null.

Thanks for reading!

Posted in SpringBootTags:
Write a comment