Eu tenho o código abaixo, que é um pouco feio para várias verificações de nulos.
String s = null;
if (str1 != null) {
s = str1;
} else if (str2 != null) {
s = str2;
} else if (str3 != null) {
s = str3;
} else {
s = str4;
}
Então tentei usar Optional.ofNullable
como abaixo, mas ainda é difícil de entender se alguém lê meu código. qual é a melhor abordagem para fazer isso no Java 8.
String s = Optional.ofNullable(str1)
.orElse(Optional.ofNullable(str2)
.orElse(Optional.ofNullable(str3)
.orElse(str4)));
No Java 9, podemos usar Optional.ofNullable
com OR
, mas no Java8 existe alguma outra abordagem?
or
sintaxe Java9String s = Optional.ofNullable(str1) .or(() -> Optional.ofNullable(str2)) .or(() -> Optional.ofNullable(str3)) .orElse(str4);
não parece tão boa quanto a queStream.of
eu faria.StringUtils.firstNonBlank()
Respostas:
Você pode fazer assim:
fonte
{str1, str2, str3}
) parece muito mais lento do que localif
ou?:
, que o tempo de execução Java pode otimizar. Existe alguma otimização específica do Stream emjavac
e o Java runtime que o torna tão rápido quanto?:
? Do contrário, não recomendarei esta solução em código de desempenho crítico.?:
código e tenho certeza que você deve evitá-lo em código de desempenho crítico. No entanto, é muito mais legível e você deve recomendá-lo em código IMO de desempenho não crítico, que tenho certeza que compõe mais de 99% do código.javac
nem no tempo de execução. Isso não impede as otimizações gerais, como embutir todo o código, seguido pela eliminação de operações redundantes. Em princípio, o resultado final poderia ser tão eficiente quanto as expressões condicionais simples; no entanto, é bastante improvável que chegue lá, pois o tempo de execução gastaria o esforço necessário apenas nos caminhos de código mais ativos.str4
aos parâmetros deStream.of(...)
e usarorElse(null)
no final.E quanto ao operador condicional ternário?
fonte
// take first non-null of str1..3
. Depois de saber o que faz, fica fácil ver como.?:
escada, saberá o que ela faz. (Aliás, os programadores funcionais conhecem isso como(cond ...)
cláusulas: é sempre um guarda seguido pelo valor apropriado a ser usado quando o guarda é verdadeiro.)Você também pode usar um loop:
fonte
As respostas atuais são boas, mas você realmente deve colocar isso em um método utilitário:
Esse método está em minha
Util
aula há anos, torna o código muito mais limpo:Você pode até torná-lo genérico:
fonte
Arrays.stream()
quando posso fazer o mesmo com afor
e a!= null
, que é mais eficiente. E Todd estaria certo. No entanto, quando codifiquei esse método, estava procurando uma maneira de fazer isso usando recursos do Java 8, assim como o OP, então é isso.Eu uso uma função auxiliar, algo como
Então, este tipo de código pode ser escrito como
fonte
v0
parâmetro extra ?min
como exemplo.) Estou menos convencido de que isso seja apropriado aqui.firstNonNull(arr)
retornar arr se não for nulo. Se fosse,firstNonNull(T... vs)
ele retornaria a primeira entrada não nula em arr.Uma solução que pode ser aplicada a quantos elementos você quiser pode ser:
Você pode imaginar uma solução como a abaixo, mas a primeira garante
non nullity
para todos os elementosfonte
str4
apesar de ser nulo, na verdadeorElseNull
, que tem o mesmo valor sestr4
for nulo.Você também pode agrupar todas as Strings em um array de String e fazer um loop for para verificar e interromper o loop depois de atribuído. Supondo que s1, s2, s3, s4 sejam todos Strings.
Editado para lançar a condição padrão para s4 se nenhum for atribuído.
fonte
s4
(oustr4
), que deve ser atribuídos
no final, mesmo que seja nulo.Método baseado e simples.
E use-o como:
É simples de fazer com arrays e é bonito.
fonte
Se você usar o Apache Commons Lang 3, ele pode ser escrito assim:
O uso de
ObjectUtils.firstNonNull(T...)
foi retirado desta resposta . Diferentes abordagens também foram apresentadas em questões relacionadas .fonte