Supposons que j'ai un value
, je le fais habituellement pour le "fixer" à une plage, ici la plage [0..1]
. C'est-à-dire s'il est en dessous du début de plage, l'augmenter jusqu'au début de plage, au-dessus de la fin de plage, le réduire jusqu'à la fin de plage.
clampedValue = Math.max(0, Math.min(1, value));
Existe-t-il une fonction intégrée pour le serrage sur une plage?
Après avoir examiné la méthode de serrage générique proposée dans une autre réponse, il convient de noter que cela a boxing/unboxing considérations pour les types primitifs.
public static <T extends Comparable<T>> T clamp(T val, T min, T max) {...}
float clampedValue = clamp(value, 0f, 1f);
Cela utilisera la classe wrapper Float
, résultant en 3 opérations de boîte, une pour chaque paramètre et 1 opération de déballage pour le type renvoyé.
Pour éviter cela, je me contenterais de l'écrire à la main ou d'utiliser une fonction non générique pour le type que vous souhaitez:
public static float clamp(float val, float min, float max) {
return Math.max(min, Math.min(max, val));
}
Ensuite, surchargez avec des méthodes identiques pour chaque type primitif dont vous avez besoin.
Existe-t-il une fonction intégrée pour le serrage sur une plage?
Non.
Depuis la version 21, Guava inclut Ints.constrainToRange()
(et méthodes équivalentes pour les autres primitives). À partir de notes de version :
ajout de méthodes
constrainToRange([type] value, [type] min, [type] max)
qui contraignent la valeur donnée à la plage fermée définie par les valeursmin
etmax
. Ils renvoient la valeur elle-même si elle est dans la plage, lemin
s'il est en dessous de la plage et lemax
s'il est au-dessus de la plage.
Porté depuis ne réponse .NET :
public static <T extends Comparable<T>> T clamp(T val, T min, T max) {
if (val.compareTo(min) < 0) return min;
else if (val.compareTo(max) > 0) return max;
else return val;
}
Attention: Contrairement à .NET, les types primitifs ne sont pas autorisés dans les génériques, ce qui signifie qu'ils doivent être encadrés/non encadrés. Lorsque vous travaillez avec des types primitifs, tels que int
et double
, cette implémentation effectuera trois opérations de boîte et une opération de déballage.
Remarque: comme il s'agit d'un port de la réponse .NET , j'ai créé ce message sur un wiki communautaire.
Une autre solution pas si jolie, mais possible est d'utiliser l'opérateur ternaire, qui est un raccourci pour le if-then-else
déclaration.
Quelques exemples:
// value must be between MIN_VALUE and MAX_VALUE
value = value > MAX_VALUE ? MAX_VALUE : value < MIN_VALUE ? MIN_VALUE : value;
// value must be between 0 and 10
value = value > 10 ? 10 : value < 0 ? 0 : value;