Aggiunte API opzionali per Java 9

1. Panoramica

In questo articolo, esamineremo le aggiunte di Java 9 all'API facoltativa .

Oltre alla modularità, Java 9 aggiunge anche tre metodi molto utili per la classe Optional .

2. Il metodo or ()

A volte, quando il nostro Opzionale è vuoto, vogliamo eseguire qualche altra azione che restituisca anch'esso un Opzionale.

Prima di Java 9, la classe Optional aveva solo i metodi orElse () e orElseGet () ma entrambi dovevano restituire valori non inclusi .

Java 9 introduce il metodo or () che restituisce pigramente un altro Opzionale se il nostro Opzionale è vuoto. Se il nostro primo Optional ha un valore definito, il lambda passato al metodo or () non verrà richiamato e il valore non verrà calcolato e restituito:

@Test public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() { //given String expected = "properValue"; Optional value = Optional.of(expected); Optional defaultValue = Optional.of("default"); //when Optional result = value.or(() -> defaultValue); //then assertThat(result.get()).isEqualTo(expected); }

Nel caso di Optional bei ng empty, il risultato restituito sarà lo stesso di defaultValue:

@Test public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() { // given String defaultString = "default"; Optional value = Optional.empty(); Optional defaultValue = Optional.of(defaultString); // when Optional result = value.or(() -> defaultValue); // then assertThat(result.get()).isEqualTo(defaultString); }

3. Il metodo ifPresentOrElse ()

Quando abbiamo un'istanza opzionale , spesso vogliamo eseguire un'azione specifica sul valore sottostante di essa. D'altra parte, se l' Operativo è vuoto , vogliamo registrarlo o tenerne traccia incrementando una metrica.

Il metodo ifPresentOrElse () viene creato esattamente per tali scenari. Possiamo passare un Consumer che verrà richiamato se è definito l' Optional e Runnable che verrà eseguito se l' Optional è vuoto.

Supponiamo di avere un Opzionale definito e di voler incrementare un contatore specifico se il valore è presente:

@Test public void givenOptional_whenPresent_thenShouldExecuteProperCallback() { // given Optional value = Optional.of("properValue"); AtomicInteger successCounter = new AtomicInteger(0); AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); // when value.ifPresentOrElse( v -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); // then assertThat(successCounter.get()).isEqualTo(1); assertThat(onEmptyOptionalCounter.get()).isEqualTo(0); }

Notare che il callback passato come secondo argomento non è stato eseguito.

Nel caso di un Opzionale vuoto , viene eseguito il secondo callback:

@Test public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() { // given Optional value = Optional.empty(); AtomicInteger successCounter = new AtomicInteger(0); AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); // when value.ifPresentOrElse( v -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); // then assertThat(successCounter.get()).isEqualTo(0); assertThat(onEmptyOptionalCounter.get()).isEqualTo(1); }

4. Il metodo stream ()

L'ultimo metodo, che viene aggiunto alla classe Optional in Java 9, è il metodo stream () .

Java ha un'API Stream molto fluente ed elegante che può operare sulle raccolte e utilizza molti concetti di programmazione funzionale. La versione più recente di Java introduce il metodo stream () sulla classe Optional che ci consente di trattare l' istanza Optional come Stream.

Diciamo che abbiamo un Opzionale definito e stiamo chiamando il metodo stream () su di esso. Questo creerà uno Stream di un elemento su cui possiamo utilizzare tutti i metodi disponibili nell'API Stream :

@Test public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() { // given Optional value = Optional.of("a"); // when List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); // then assertThat(collect).hasSameElementsAs(List.of("A")); }

D'altra parte, se Optional non è presente, la chiamata al metodo stream () su di esso creerà uno Stream vuoto :

@Test public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() { // given Optional value = Optional.empty(); // when List collect = value.stream() .map(String::toUpperCase) .collect(Collectors.toList()); // then assertThat(collect).isEmpty(); }

Ora possiamo filtrare rapidamente flussi di opzioni.

Operare sullo Stream vuoto non avrà alcun effetto, ma grazie al metodo stream () ora possiamo concatenare l' API opzionale con l' API Stream . Questo ci permette di creare un codice più elegante e scorrevole.

5. conclusione

In questo rapido articolo, abbiamo esaminato le aggiunte API facoltative di Java 9 .

Abbiamo visto come utilizzare il metodo or () per restituire un Opzionale nel caso in cui l'origine Opzionale sia vuota. Abbiamo utilizzato ifPresentOrElse () per eseguire il Consumer se il valore è presente e in caso contrario, eseguire un altro callback.

Infine, abbiamo visto come concatenare l' Opzionale con l' API Stream utilizzando il metodo stream () .

L'implementazione di tutti questi esempi e frammenti di codice può essere trovata nel progetto GitHub: questo è un progetto Maven, quindi dovrebbe essere facile da importare ed eseguire così com'è.