假设我有一个value,我通常会这样做"钳制"它到一个范围,这里是范围[0..1].也就是说,如果它低于范围开始,则将其增加到范围开始,将其增加到范围结束,将其减小到范围结束.
clampedValue = Math.max(0, Math.min(1, value));
是否有内置功能可以夹紧到一个范围内?
Mat*_*all 157
是否有内置功能可以夹紧到一个范围内?
没有.
wes*_*ton 42
看过另一个答案中提供的通用钳位方法,值得注意的是,它具有原始类型的装箱/拆箱考虑因素.
public static <T extends Comparable<T>> T clamp(T val, T min, T max) {...}
float clampedValue = clamp(value, 0f, 1f);
这将使用Float包装器类,导致3个盒子操作,每个参数一个,以及返回类型的1个unbox操作.
为了避免这种情况,我会坚持长手写或者使用非泛型函数来获得你想要的类型:
public static float clamp(float val, float min, float max) {
    return Math.max(min, Math.min(max, val));
}
然后只需为您需要的每种基本类型重载相同的方法.
dim*_*414 17
从版本21开始,Guava包含Ints.constrainToRange()(以及其他基元的等效方法).从发行说明:
添加
constrainToRange([type] value, [type] min, [type] max)了将给定值约束到由min和max值定义的闭合范围的方法.如果它在范围内,它们返回值本身,如果它在范围min之下,max如果它在范围之上,则返回值.
Ada*_*ent 15
从.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;
}
警告:与.NET不同,泛型中不允许使用原始类型,这意味着必须将它们装箱/取消装箱.使用原始类型(例如int和)时double,此实现将执行三个盒操作和一个unbox操作.
注意:因为它是.NET答案的一个端口,所以我将其作为社区维基帖.
另一个不太漂亮但可能的解决方案是使用三元运算符,它是if-then-else语句的简写。
一些例子:
// 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;