Tengo el siguiente código que es un poco feo para múltiples comprobaciones nulas.
String s = null;
if (str1 != null) {
s = str1;
} else if (str2 != null) {
s = str2;
} else if (str3 != null) {
s = str3;
} else {
s = str4;
}
Así que intenté usar Optional.ofNullablecomo se muestra a continuación, pero aún es difícil de entender si alguien lee mi código. cuál es el mejor enfoque para hacerlo en Java 8.
String s = Optional.ofNullable(str1)
.orElse(Optional.ofNullable(str2)
.orElse(Optional.ofNullable(str3)
.orElse(str4)));
En Java 9, podemos usar Optional.ofNullablecon OR, pero en Java8, ¿hay algún otro enfoque?

orsintaxis de Java9String s = Optional.ofNullable(str1) .or(() -> Optional.ofNullable(str2)) .or(() -> Optional.ofNullable(str3)) .orElse(str4);no se ve tan bien como la queStream.ofyo haría.StringUtils.firstNonBlank()Respuestas:
Puedes hacerlo así:
fuente
{str1, str2, str3}) parece mucho más lento que un localifo?:, que el tiempo de ejecución de Java puede optimizar. ¿Hay alguna optimización específica de Streamjavacy el tiempo de ejecución de Java que lo hace tan rápido como?:? De lo contrario, no recomendaré esta solución en código de rendimiento crítico.?:código y estoy seguro de que debería evitarlo en el código de rendimiento crítico. Sin embargo, es mucho más legible y debería recomendarlo en un código que no es crítico para el rendimiento, en mi opinión, que estoy seguro de que genera más del 99% del código.javacni en el tiempo de ejecución. Esto no excluye las optimizaciones generales, como incluir todo el código, seguido de la eliminación de operaciones redundantes. En principio, el resultado final podría ser tan eficiente como las expresiones condicionales simples, sin embargo, es bastante poco probable que llegue allí, ya que el tiempo de ejecución gastaría el esfuerzo necesario solo en las rutas de código más calientes.str4a los parámetros deStream.of(...)y usarorElse(null)al final.¿Qué hay del operador condicional ternario?
fuente
// take first non-null of str1..3. Una vez que sepa lo que hace, es fácil ver cómo.?:escalera, sabrá lo que hace. (Por cierto, los programadores funcionales saben esto como(cond ...)cláusulas:. Siempre es un guardia seguido por el valor apropiado utilizar cuando el guardia es verdad)También puede utilizar un bucle:
fuente
Las respuestas actuales son buenas, pero realmente deberías ponerlas en un método de utilidad:
Ese método ha estado en mi
Utilclase durante años, hace que el código sea mucho más limpio:Incluso puedes hacerlo genérico:
fuente
Arrays.stream()cuando puedo hacer lo mismo con ayfora!= null, que es más eficiente. Y Todd tendría razón. Sin embargo, cuando codifiqué este método, estaba buscando una forma de hacerlo usando las funciones de Java 8, al igual que OP, así que ahí está.Yo uso una función auxiliar, algo así como
Entonces este tipo de código se puede escribir como
fuente
v0parámetro extra ?mincomo ejemplo). Estoy menos convencido de que esto sea apropiado aquí.firstNonNull(arr)devolver arr si no es nulo. Si lo fuerafirstNonNull(T... vs), devolvería la primera entrada no nula en arr.Una solución que se puede aplicar a tantos elementos como desee puede ser:
Podrías imaginar una solución como la siguiente, pero la primera asegura
non nullitytodos los elementos.fuente
str4pesar de que sea un nulo en realidadorElseNull, que equivale a lo mismo sistr4es nulo.También puede agrupar todas las cadenas en una matriz de cadenas y luego hacer un bucle for para verificar y romper el bucle una vez que esté asignado. Suponiendo que s1, s2, s3, s4 son todas cadenas.
Editado para poner en condición por defecto a s4 si no se asigna ninguno.
fuente
s4(ostr4), que se supone que se asignará alsfinal, incluso si es nulo.Método sencillo y basado en el método.
Y utilícelo como:
Es fácil de hacer con matrices y se ve bonito.
fuente
Si usa Apache Commons Lang 3, entonces se puede escribir así:
Se
ObjectUtils.firstNonNull(T...)tomó el uso de esta respuesta . También se presentaron diferentes enfoques en una pregunta relacionada .fuente