假设我有一个值
,通常我会这样做来将其限制在一个范围内,这里的范围是[0..1]
。也就是说,如果它低于范围开始值,则增加到范围开始值,如果高于范围结束值,则减少到范围结束值。
clampedValue = Math.max(0, Math.min(1, value));
是否有内置函数可以将值夹在特定范围内?
假设我有一个值
,通常我会这样做来将其限制在一个范围内,这里的范围是[0..1]
。也就是说,如果它低于范围开始值,则增加到范围开始值,如果高于范围结束值,则减少到范围结束值。
clampedValue = Math.max(0, Math.min(1, value));
是否有内置函数可以将值夹在特定范围内?
看了另一个答案中提供的通用夹具方法后,值得注意的是这对原始类型有装箱/拆箱的考虑。
public static <T extends Comparable<T>> T clamp(T val, T min, T max) {...}
float clampedValue = clamp(value, 0f, 1f);
这将使用 Float
包装类,会产生3个装箱操作,每个参数一个,并返回一个拆箱操作的类型。
为了避免这种情况,我建议要么手写代码,要么使用非泛型函数来获得所需类型:
public static float clamp(float val, float min, float max) {
return Math.max(min, Math.min(max, val));
}
Guava 包含了 Ints.constrainToRange()
(以及其他原始类型的等效方法)。从发行说明中可以看到:
添加了
constrainToRange([type] value, [type] min, [type] max)
方法,将给定值约束在由min
和max
值定义的封闭范围内。如果它在该范围内,则返回该值本身;如果它低于该范围,则返回min
;如果它高于该范围,则返回max
。
Range.between(0.0, 1.0).fit(0.5); // 返回 0.5
- Marty Neal这篇文章是从.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
)时,此实现将执行三次装箱操作和一次拆箱操作。
注意:由于这是.NET答案的移植版本,因此我将其作为社区wiki帖子发布。
还有一种不太美观但可能的解决方案是使用三元运算符,它是“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;
JavaFX:
Utils.clamp(min, value, max)
kotlin:
value.coerceIn(min, max)