java clamp

¿Java tiene una función de abrazadera?



clamp (5)

¿Hay alguna función incorporada para sujetar a un rango?

No.

Supongamos que tengo un value , generalmente hago esto para "sujetarlo" a un rango, aquí el rango [0..1] . Es decir, si está por debajo del rango de inicio, increméntelo al inicio del rango, por encima del extremo del rango, y al final del rango.

clampedValue = Math.max(0, Math.min(1, value));

¿Hay alguna función incorporada para sujetar a un rango?


A partir de la versión 21, Guava incluye Ints.constrainToRange() (y métodos equivalentes para las otras primitivas). De las notas de la versión :

se agregaron los métodos constrainToRange([type] value, [type] min, [type] max) que limitan el valor dado al rango cerrado definido por los valores min y max . Devuelven el valor en sí mismo si está dentro del rango, el min si está por debajo del rango y el max si está por encima del rango.


Después de haber examinado el método de abrazadera genérica ofrecido en otra respuesta, vale la pena señalar que esto tiene consideraciones de boxing/unboxing para los tipos primitivos.

public static <T extends Comparable<T>> T clamp(T val, T min, T max) {...} float clampedValue = clamp(value, 0f, 1f);

Esto utilizará la clase de contenedor Float , lo que resulta en 3 operaciones de cuadro, una para cada parámetro y una operación de unbox para el tipo devuelto.

Para evitar esto, me limitaría a escribirlo a mano larga o usar una función no genérica para el tipo que desee:

public static float clamp(float val, float min, float max) { return Math.max(min, Math.min(max, val)); }

Luego simplemente sobrecargue con métodos idénticos para cada tipo primitivo que requiera.


Otra solución no tan bonita, pero posible es usar el operador ternario, que es una abreviatura de la declaración if-then-else .

Algunos ejemplos:

// 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;


Portado desde una respuesta .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; }

Precaución: a diferencia de .NET, los tipos primitivos no están permitidos en los genéricos, lo que significa que deben estar en caja / sin caja. Cuando se trabaja con tipos primitivos, como int y double , esta implementación realizará tres operaciones de caja y una operación de caja única.

Nota: dado que es un puerto de la respuesta de .NET , hice esto una publicación wiki de la comunidad.