Existe-t-il un équivalent Java de la COALESCE
fonction SQL ? Autrement dit, existe-t-il un moyen de renvoyer la première valeur non nulle de plusieurs variables?
par exemple
Double a = null;
Double b = 4.4;
Double c = null;
Je veux en quelque sorte une déclaration qui renverra la première valeur non nulle a
, b
et c
- dans ce cas, il retournerait b
ou 4.4. (Quelque chose comme la méthode sql - return COALESCE(a,b,c)
). Je sais que je peux le faire explicitement avec quelque chose comme:
return a != null ? a : (b != null ? b : c)
Mais je me suis demandé s'il y avait une fonction intégrée et acceptée pour accomplir cela.
Réponses:
Non, il n'y en a pas.
Le plus proche que vous pouvez obtenir est:
Pour des raisons d'efficacité, vous pouvez gérer les cas courants comme suit:
la source
coalesce(a, b)
, sib
est une expression complexe eta
ne l'est pasnull
,b
est toujours évalué. Ce n'est pas le cas pour l'opérateur conditionnel?:. Voyez cette réponse .Apache Commons Lang 3
ObjectUtils.firstNonNull(T...)
Flux Java 8
Stream.of(T...).filter(Objects::nonNull).findFirst().orElse(null)
la source
S'il n'y a que deux variables à vérifier et que vous utilisez Guava, vous pouvez utiliser MoreObjects.firstNonNull (T d'abord, T ensuite) .
la source
S'il n'y a que deux références à tester et que vous utilisez Java 8, vous pouvez utiliser
Si vous importez statique Facultatif, l'expression n'est pas trop mauvaise.
Malheureusement, votre cas avec "plusieurs variables" n'est pas possible avec une méthode optionnelle. Au lieu de cela, vous pouvez utiliser:
la source
Suite à la réponse de LES2, vous pouvez éliminer certaines répétitions dans la version efficace, en appelant la fonction surchargée:
la source
varargs
. Ici, vous gaspillez de la mémoire en créant un cadre de pile pour chaquecoalesce()
appel imbriqué . L'appelcoalesce(a, b, c, d, e)
crée jusqu'à 3 cadres de pile à calculer.Cette situation nécessite un préprocesseur. Parce que si vous écrivez une fonction (méthode statique) qui sélectionne la première valeur non nulle, elle évalue tous les éléments. C'est un problème si certains éléments sont des appels de méthode (peuvent être des appels de méthode coûteux en temps). Et ces méthodes sont appelées même si un élément avant elles n'est pas nul.
Certains fonctionnent comme ça
devrait être utilisé mais avant la compilation en code octet, il devrait y avoir un préprocesseur qui trouve les utilisations de cette «fonction de coalescence» et la remplace par une construction comme
Mise à jour 02/09/2014:
Grâce à Java 8 et Lambdas, il est possible d'avoir une véritable fusion en Java! Y compris la caractéristique cruciale: les expressions particulières ne sont évaluées que lorsque cela est nécessaire - si la précédente n'est pas nulle, les suivantes ne sont pas évaluées (les méthodes ne sont pas appelées, le calcul ou les opérations disque / réseau ne sont pas effectués).
J'ai écrit un article à ce sujet Java 8: coalesce - hledáme neNULLové hodnoty - (écrit en tchèque, mais j'espère que les exemples de code sont compréhensibles pour tout le monde).
la source
Avec Guava, vous pouvez faire:
qui ne jette pas de NPE si les deux
a
etb
sontnull
.EDIT: je me suis trompé, il jette NPE. La bonne manière, comme le commente Michal Čizmazia, est:
la source
java.lang.NullPointerException: use Optional.orNull() instead of Optional.or(null)
Optional.fromNullable(a).or(Optional.fromNullable(b)).orNull()
Pour être complet, le cas «plusieurs variables» est en effet possible, mais pas du tout élégant. Par exemple, pour les variables
o
,p
etq
:Veuillez noter qu'il est utile de
orElseGet()
s'occuper du cas quio
,p
etq
ne sont pas des variables mais des expressions coûteuses ou avec des effets secondaires indésirables.Dans le cas le plus général
coalesce(e[1],e[2],e[3],...,e[N])
Cela peut générer des expressions excessivement longues. Cependant, si nous essayons de passer à un monde sans
null
, alorsv[i]
sont très probablement déjà de typeOptional<String>
, par opposition à simplementString
. Dans ce cas,ou dans le cas d'expressions:
De plus, si vous prépare également à un style fonctionnel déclarative,
o
,p
etq
devrait être de typeSupplier<String>
comme dans:Et puis le tout
coalesce
réduit simplement ào.get()
.Pour un exemple plus concret:
defaultAgeFromDatabase()
,ageFromDatabase()
etageFromInput()
reviendraient déjàOptional<Integer>
, naturellement.Et puis le
coalesce
devienteffectiveAge.get()
ou simplementeffectiveAge
si nous sommes satisfaits d'unSupplier<Integer>
.IMHO, avec Java 8, nous verrons de plus en plus de code structuré comme celui-ci, car il est extrêmement auto-explicatif et efficace en même temps, en particulier dans les cas plus complexes.
Je manque une classe
Lazy<T>
qui n'invoqueSupplier<T>
qu'une seule fois, mais paresseusement, ainsi que la cohérence dans la définition deOptional<T>
(ieOptional<T>
-Optional<T>
opérateurs, ou mêmeSupplier<Optional<T>>
).la source
Vous pouvez essayer ceci:
Basé sur cette réponse
la source
Que diriez-vous d'utiliser des fournisseurs lorsque vous voulez éviter d'évaluer une méthode coûteuse?
Comme ça:
Et puis en l'utilisant comme ceci:
Vous pouvez également utiliser des méthodes surchargées pour les appels avec deux, trois ou quatre arguments.
De plus, vous pouvez également utiliser des flux avec quelque chose comme ceci:
la source
Supplier
s'il sera inspecté de toute façon? Par souci d'uniformité?Que diriez-vous:
Java ArrayList autorise commodément les entrées nulles et cette expression est cohérente quel que soit le nombre d'objets à prendre en compte. (Sous cette forme, tous les objets considérés doivent être du même type.)
la source
la source
Double
est loin d'être idéal. Je ne savais tout simplement pas que les fonctions statiques pouvaient recevoir des paramètres de type. Je pensais que c'était juste des cours.