Java - 将数字限制在最小值和最大值之间

53

我希望能够在限制范围内返回一个数字,否则返回该范围的最大或最小值。我可以通过使用Math.minMath.max的组合来实现这一点。

public int limit(int value) {
    return Math.max(0, Math.min(value, 10));
}

我想知道是否有我忽略了的现有limitrange函数。
如果它们是相当常见的第三方库(例如: Commons或Guava),那么欢迎使用。


5
那是正确的模式。如果你在多个地方都这么做,可以在一个辅助类中定义自己的方法。 - Jim Garrison
4
如果这段代码看起来太长,可以将其包装在你自己的函数中。 - Robert Harvey
4
我来到社区看看是否已经存在这样的功能。只是一个问题...我不认为这是一个坏问题? - Sean Connolly
1
这不是一个坏问题。你展示了你已经做了什么,并且具体询问是否有一种方法解决。当存在更简单的解决方案时,没有人想显得无知地重复造轮子。不确定为什么会被踩,但我点赞以帮助抵消它。 - Trevor Freeman
1
@RobertHarvey 我也在想同样的问题。这似乎非常简单。我猜这只是数学家们期望已经内置于数学库中的东西。 - But I'm Not A Wrapper Class
显示剩余3条评论
8个回答

32

OP希望这个实现被纳入标准库:

int ensureRange(int value, int min, int max) {
   return Math.min(Math.max(value, min), max);
}

boolean inRange(int value, int min, int max) {
   return (value>= min) && (value<= max);
}

可惜标准的 Math 库缺少了这些功能


2
此外,基于C的编程语言缺乏明显的惯用语“(min <= value <= max)”,这让新手们感到非常困扰。 - Hot Licks
2
我认为ensureRange应该反过来:int ensureRange(int value, int min, int max) { return Math.min(Math.max(value, min), max); }这是将其放入库中的好理由。这样你只需要犯一次错误就可以了;-) - Renso Lohuis
@RensoLohuis 微不足道的问题:我想让 minmax 之前执行。阅读顺序 != 执行顺序。 - Barry Staes
1
@BarryStaes 我不是在谈论执行顺序。你有 Math.min(value, min),这不会帮助你确保范围。如果 value = 3,min = 5,Math.min 将返回 3,因此它将不会保持在范围内。对于 Math.max(value, max) 也是一样的。因此,这个函数不能确保范围。 - Renso Lohuis
@RensoLohuis 谢谢指出问题!抱歉我脑子一短路,现在已经修复。 - Barry Staes

18

我知道这个问题是关于Java的。在Android世界中,通常会同时使用Kotlin和Java。如果有一些Kotlin用户到达这里(就像我一样),那么他们可以使用coerceIn扩展函数:

Kotlin代码:

println(10.coerceIn(1, 100)) // 10
println(10.coerceIn(1..100)) // 10
println(0.coerceIn(1, 100)) // 1
println(500.coerceIn(1, 100)) // 100

请到官方 Kotlin 文档 了解更多信息。


15

从版本21开始,Guava 包含Ints.constrainToRange() (以及其他基元类型的等效方法)。根据发行说明

新增了constrainToRange([type] value, [type] min, [type] max) 方法,它将给定值限制在由 minmax 值定义的闭区间范围内。如果该值在范围内,则返回该值本身;如果低于范围,则返回 min;如果高于范围,则返回 max

转自 @dimo414 的https://dev59.com/5mQn5IYBdhLWcg3wroqL#42968254

不幸的是,这个版本在2017年7月还比较新,在某些项目中(参见https://dev59.com/H1oU5IYBdhLWcg3w_apI#40691831),Guava 打破了向后兼容性,这迫使我目前仍需使用版本19。我也很惊讶 Commons Lang 和 Commons Math 都没有此功能! :(


13

如果您使用的是 Android 系统,请使用 MathUtils(在支持库中),它只有一个名为 clamp 的函数,可以确保数值落在给定的数值范围内。

此方法接受一个数值,并确保其适合于给定的数值范围。如果该数小于范围所要求的最小值,则返回范围的最小值。如果该数大于范围允许的最大值,则返回该范围的最大值。


2
很好。只是为了记录,一个使用示例:MathUtils.clamp( value, min, max ) - davee44

5

Math.max(int a, int b)函数的定义如下:

public static int min(int a, int b) {
    return (a <= b) ? a : b;
}

所以您可以将maxmin函数组合如下:
private static int MAX=10;
private static int MIN=0;

public int limit(int a) {
    return (a > MAX) ? MAX : (a < MIN ? MIN: a );
}

4

为任何实现Comparable接口的类(包括Number及其子类)提供通用方法:

public static <T extends Comparable<? super T>> T limit(T o, T min, T max){
    if (o.compareTo(min) < 0) return min;
    if (o.compareTo(max) > 0) return max;
    return o;
}

唯一的要求是所有参数必须属于同一类。这可以防止可能的类型转换损失。实际上,将floatdoublelongint进行比较是不正确的。例如,(double) 0.1 != (float) 0.1

用法:

double x = 13.000000001;
x = limit(x, 12.0, 13.0);
System.out.println("x = " + x); //x = 13.0

很不幸,通过limit(x, 12.0, 13.0)直接更改第一个参数是不可能的,因为原始类型是不可变的。


2
Java 21中新增了一个方便地将数值限制在指定最小值和最大值之间的Math.clamp方法(具有多个重载)。
int valueToClamp = 0;

System.out.println(Math.clamp(valueToClamp, 1, 10)); // 1

public static int clamp(long value, int min, int max)

  • value - 需要夹取的值
  • min - 允许的最小值
  • max - 允许的最大值

-5

你不需要外部库来完成这个任务,可以尝试以下测试用例:

public class RandomNumber {

    public static void main(String[] Args) {
        System.out.println("random = " + randomInRange(5,10));
    }
    
    public static double randomInRange(double arg1, double arg2) {
        double my_number = Math.ceil(Math.random() * (arg1 - arg2) + arg2);
        return my_number;
    }

}

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