Today, at work, I had the dire need of discriminated unions in Java, which of course doesn’t support it. Then I found the idea of the Either type, which I implemented myself using the Optional class from Java 8:
import java.util.Optional;
import java.util.function.Consumer;
/**
* Guarda 3 elementos mutuamente exclusivos, isto é, apenas 1 dos 3 pode existir
* dentro do objeto.
*/
public class Either3<T1, T2, T3> {
private Optional<T1> v1 = Optional.empty();
private Optional<T2> v2 = Optional.empty();
private Optional<T3> v3 = Optional.empty();
/** Cria um objeto com o valor do tipo 1. */
public static <<1, T2, T3> Either3<T1, T2, T3> of1(T1 v1) {
Either3<T1, T2, T3> obj = new Either3<>();
obj.v1 = Optional.of(v1);
return obj;
}
/** Cria um objeto com o valor do tipo 1. */
public static <T1, T2, T3> Either3<T1, T2, T3> of2(T2 v2) {
Either3<T1, T2, T3> obj = new Either3<>();
obj.v2 = Optional.of(v2);
return obj;
}
/** Cria um objeto com o valor do tipo 1. */
public static <T1, T2, T3> Either3<T1, T2, T3> of3(T3 v3) {
Either3<T1, T2, T3> obj = new Either3<
obj.v3 = Optional.of(v3);
return obj;
}
/** Retorna o valor do tipo 1; caso não exista, lança {@code NoSuchElementException}. */
public T1 get1() {
return v1.get();
}
/** Retorna o valor do tipo 2; caso não exista, lança {@code NoSuchElementException}. */
public T2 get2() {
return v2.get();
}
/** Retorna o valor do tipo 3; caso não exista, lança {@code NoSuchElementException}. */
public T3 get3() {
return v3.get();
}
/** Diz se o objeto possui um valor do tipo 1. */
public boolean has1() {
return v1.isPresent();
}
/** Diz se o objeto possui um valor do tipo 2. */
public boolean has2() {
return v2.isPresent();
}
/** Diz se o objeto possui um valor do tipo 3. */
public boolean has3() {
return v3.isPresent();
}
/** Executa a função caso haja um valor do tipo 1. */
public void if1(Consumer<? super T1> consumer) {
v1.ifPresent(consumer);
}
/** Executa a função caso haja um valor do tipo 2. */
public void if2(Consumer<? super T2> consumer) {
v2.ifPresent(consumer);
}
/** Executa a função caso haja um valor do tipo 3. */
public void if3(Consumer<? super T3> consumer) {
v3.ifPresent(consumer);
}
}
Since Java doesn’t have variadic generic parameters, having one class to each amount is needed. Nonetheless, it’s doable and remarkably ergonomic.
No comments:
Post a Comment