Java有夹紧函数吗?

82

假设我有一个,通常我会这样做来将其限制在一个范围内,这里的范围是[0..1]。也就是说,如果它低于范围开始值,则增加到范围开始值,如果高于范围结束值,则减少到范围结束值。

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

是否有内置函数可以将值夹在特定范围内?


@LuiggiMendoza HLSL - weston
请参见 https://dev59.com/BHE85IYBdhLWcg3wpFEa? - Adam Gent
1
@LuiggiMendoza 还有OpenGL - weston
1
@AdamGent 很明显,编写自己的函数是微不足道的,我已经在问题中提供了代码。我宁愿使用内置的函数,特别是因为它可以处理所有值数据类型。 - weston
3
我不太了解你在Java方面的专业水平,因此很难假设你的知识水平。 C#使用Comparable来处理多个数据类型...猜猜你在Java中做什么 :) - Adam Gent
显示剩余2条评论
7个回答

200
编辑,2023年秋季:这个答案已经过时了!请参阅这个更新的答案,了解Java 21的最新信息。
有没有内置函数可以将值限制在一个范围内?
没有。

23
很遗憾,由于这个重大缺陷,我不能再向其他开发者推荐Java了。(开玩笑的,虽然我认为他们应该把它包括在内。) - Venryx
@Venryx 有很多其他不推荐使用Java的原因。朋友们不会让朋友们用Java :-P - lmat - Reinstate Monica
6
对于未来的访问者:这正在变化。请查看Michael Berry的答案 - Ben I.

56

看了另一个答案中提供的通用夹具方法后,值得注意的是这对原始类型有装箱/拆箱的考虑。

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));
}

然后,只需为您需要的每种原始类型重载相同的方法。

27

Guava 包含了 Ints.constrainToRange()(以及其他原始类型的等效方法)。从发行说明中可以看到:

添加了 constrainToRange([type] value, [type] min, [type] max) 方法,将给定值约束在由 minmax 值定义的封闭范围内。如果它在该范围内,则返回该值本身;如果它低于该范围,则返回 min;如果它高于该范围,则返回 max


3
对于使用 Apache commons lang3 而不是 Guava 的用户,可以使用 Range.fit 方法。Range.between(0.0, 1.0).fit(0.5); // 返回 0.5 - Marty Neal
他们在3.10版中添加了以下内容:https://commons.apache.org/proper/commons-lang/changes-report.html#a3.10 - jgibson

17

这篇文章是从.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不同,泛型中不允许使用原始类型,这意味着必须进行装箱/拆箱。在使用原始类型(如intdouble)时,此实现将执行三次装箱操作和一次拆箱操作。

注意:由于这是.NET答案的移植版本,因此我将其作为社区wiki帖子发布。


13

还有一种不太美观但可能的解决方案是使用三元运算符,它是“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;

1
我喜欢这个一行代码。它很简洁! - JSong
3
我运行了几千次迭代,与@weston提供的原始方法相比,这似乎只需要大约3/4的时间来计算。绝对比使用Min/Max函数更有效率。 - Fire 'N Lightnin'

12

1
这可能与问题无关,但如果有人在寻找JavaFX或Kotlin中的相同功能,就像我一样,这里有:

JavaFX:

Utils.clamp(min, value, max)

kotlin:

value.coerceIn(min, max)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接