Fai attenzione con il metodo Java opzionale
Fonte:
Dev.to Secondo Oracle, un oggetto
opzionale è "un oggetto contenitore che può o meno contenere un valore non nullo". Opzionale è apparso per la prima volta in Java 8 ed è stato utilizzato dal team SpringBoot in molti progetti. L'uso più comune degli
optional è in un progetto Spring Data. Diamo un'occhiata all'interfaccia JpaRepository e ad un metodo di esempio. Ad esempio, abbiamo un oggetto
Utente con un Id di tipo intero e abbiamo un JpaRepository per esso.
@Repository
public interface IUserRepo extends JpaRepository<User, Integer>
{
Optional<User> findByUserName(String userName);
}
Abbiamo definito un metodo che cerca un utente in base al suo nome e restituisce
un Optional per
User .
Metodi convenienti Opzionali
Facoltativo è incluso in molti metodi che ci consentono di scrivere codice pulito e leggibile.
- mappa(..).o(...)
- mappa(...).oAltro(...)
- un elenco completo può essere trovato nella documentazione Oracle .
Tuttavia, esiste un metodo con un comportamento pericolosamente inaspettato.
Scopri il metodo orElse
Secondo la documentazione Oracle:
public T orElse(T other)
Restituisce il valore se ce n'è uno, altrimenti restituisce qualcos'altro. Ora possiamo aggiungere una chiamata al metodo come parametro
orElse che verrà eseguito se il parametro
Opzionale è vuoto, giusto? Sì, è corretto, ma cosa succederebbe se ti dicessi che funzionerà comunque, indipendentemente dal fatto che ci sia un valore in
Opzionale o meno. Controlliamo:
@Test
public void orElseTest()
{
String result = Optional.of("hello").orElse(someMethod());
assertThat(result).isEqualTo("hello");
}
private String someMethod()
{
System.out.println("I am running !!");
return "hola";
}
Il test ha avuto esito positivo, ma noterete che sulla console è stampata la riga “
Sto correndo ”.
Perché sta succedendo?
Java esegue un metodo per fornire il valore che verrà restituito nel caso di
Else .
Perciò stai attento!
Devi fare attenzione se un metodo inside
orElse potrebbe avere un effetto collaterale perché verrà comunque eseguito.
Cosa fare?
È possibile utilizzare il metodo
OrElseGet , che accetta un metodo del fornitore da eseguire se esiste
Facoltativo .
Come visualizzare e sommare elementi da un elenco in Java
Fonte:
DZone In questo post imparerai come visualizzare e riepilogare il numero di elementi da un elenco in Java. Mappare elementi da un elenco
significa che ogni elemento in quell'elenco verrà convertito in un oggetto diverso. Sommare gli elementi di un elenco significa che tutti gli elementi di quell'elenco verranno combinati in un unico oggetto, che non è necessariamente dello stesso tipo di quello originale. Diciamo che abbiamo un elenco di ordini e ogni ordine ha un elenco di prodotti.
record Order(String customer, List<Product> products) {
}
record Product(String brand, String modelName, BigDecimal price) {
}
Cosa faresti se volessi sapere quanti soldi provengono da un elenco di ordini? Per ogni ordine sarà necessario ottenere l'elenco dei prodotti in esso presenti e per ogni prodotto presente in tali elenchi sarà necessario ottenere il relativo costo. Successivamente, devi sommare tutti questi prezzi ed è così che ottieni il risultato. Quando si traduce quanto sopra in
Mappa /
Riduci è necessario:
- Abbina ogni ordine a un elenco di prodotti.
- Visualizza il prezzo per ciascun prodotto.
- Somma tutti i prezzi sommandoli insieme.
Quindi facciamolo in Java:
public class OrderMapReducer {
public BigDecimal getTotal(List<Order> orders) {
return orders.stream()
.map(Order::products)
.flatMap(List::stream)
.map(Product::price)
.reduce(BigDecimal::add)
.orElse(BigDecimal.ZERO);
}
}
- Creiamo un flusso di ordini.
- Abbiniamo ogni ordine alla sua lista di prodotti.
- Abbiniamo ogni elenco di prodotti a un flusso. Tieni presente che qui dobbiamo utilizzare flatMap , altrimenti ci ritroveremmo con Stream <Stream <Product>> .
- Per ogni prodotto mostriamo il suo prezzo.
- Riassumiamo tutti i prezzi.
- Se l'Elenco ordini è vuoto, restituisce zero.
È tutto! Ora possiamo creare un test per assicurarci che tutto funzioni come previsto.
@Test
void getTotalPrice() {
List<Order> orders = createOrders();
OrderMapReducer orderMapReducer = new OrderMapReducer();
assertEquals(new BigDecimal(17800), orderMapReducer.getTotal(orders));
}
private static List<Order> createOrders() {
var strato = new Product("Fender", "Stratocaster", new BigDecimal(3500));
var sg = new Product("Gibson", "SG", new BigDecimal(4800));
var lesPaul = new Product("Gibson", "Les Paul", new BigDecimal(4500));
var rr = new Product("Jackson", "RR", new BigDecimal(5000));
return List.of(
new Order("David Gilmour", List.of(strato)),
new Order("Toni Iommi", List.of(sg)),
new Order("Randy Rhoads", List.of(lesPaul, rr))
);
}
Come puoi vedere, Map and Reduce aiuta nei casi in cui è necessario estrarre informazioni da
una raccolta .
GO TO FULL VERSION