Suppose I have a value
, I usually do this to "clamp" it to a range, here the range [0..1]
. That is if it is below the range start, increase it to the range start, it above the range end, reduce it to the range end.
clampedValue = Math.max(0, Math.min(1, value));
Is there any built in function for clamping to a range?
Is there any built in function for clamping to a range?
No.
Having looked at the generic clamp method offered up in another answer, it is worth noting that this has boxing/unboxing considerations for primitive types.
public static <T extends Comparable<T>> T clamp(T val, T min, T max) {...}
float clampedValue = clamp(value, 0f, 1f);
This will use the Float
wrapper class, resulting in 3 box operations, one for each parameter, and 1 unbox operation for the returned type.
To avoid this, I would just stick to writing it long hand or use a non-generic function for the type you want:
public static float clamp(float val, float min, float max) {
return Math.max(min, Math.min(max, val));
}
Then just overload with identical methods for every primitive type you require.
As of version 21, Guava includes Ints.constrainToRange()
(and equivalent methods for the other primitives). From the release notes:
added
constrainToRange([type] value, [type] min, [type] max)
methods which constrain the given value to the closed range defined by themin
andmax
values. They return the value itself if it's within the range, themin
if it's below the range and themax
if it's above the range.
Ported from a .NET answer:
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;
}
Caution: Unlike .NET, primitive types are not allowed in generics, which means they must be boxed/unboxed. When working with primitive types, such as int
and double
, this implementation will perform three box operations and one unbox operation.
Note: since it’s a port of the .NET answer, I made this a community wiki post.
Another not so pretty, but possible solution is to use the ternary operator, which is a shorthand for the if-then-else
statement.
Some Examples:
// 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;
来源:https://stackoverflow.com/questions/16656651/does-java-have-a-clamp-function