概述

本教程将探讨检查给定范围中是否存在整数的方法。我们将使用运算符以及几个实用类来实现这一目标。

2. 范围类型

在使用这些方法之前,我们需要明确我们讨论的是哪种类型的范围。在整个教程中,我们将关注以下四种有界范围类型:

  • 闭区间 - 包含其下限和上限
  • 开区间 - 不包含其下限和上限
  • 左开右闭区间 - 包含其上限,但不包含其下限
  • 左闭右开区间 - 包含其下限,但不包含其上限

例如,如果我们想知道整数20是否存在于这两个区间:*R1 = [10, 20)*,一个左闭右开区间,以及 *R2 = (10, 20]*,一个左开右闭区间。由于 R1 不包含其上限,因此整数20仅存在于 R2 中。

3. 使用 <<= 运算符

我们的目标是确定一个数字是否在给定的上下限之间。我们将首先使用基本的Java运算符来检查这一点。

让我们定义一个类,用于所有四种类型的区间检查:

public class RangeChecker {
    // ...
}

通过改变运算符以包括或排除边界,我们可以调整区间以使其为开放、关闭或半开半闭。

现在让我们测试我们的 isInOpenClosedRange() 静态方法。我们将指定左开右闭区间 (10,20]*,通过传递下限10和上限20:

RangeChecker.check(10, 20, 20); // 测试10是否在(10,20]内
RangeChecker.check(10, 20, 10); // 测试10是否在(10,20]内

在第一个测试中,我们成功验证了整数20存在于(10,20]范围内,它包含其上限。然后我们确认整数10不在此范围内,因为它排除了其下限。

4. 使用范围类

除了使用Java运算符,我们还可以使用代表范围的实用类。使用预定义类的主要优点是范围类提供了对上述描述的一些或全部范围类型的现成实现

此外,我们可以配置一个范围对象,用我们定义的边界,并在其他方法或类中重用它。通过一次定义范围,如果我们的代码库中有多个针对同一范围的检查,我们的代码将更少出错。

然而,下面我们将看到的两个范围类来自外部库,必须在使用它们之前导入到我们的项目中。

4.1. 使用 java.time.temporal.ValueRange

不需要导入外部库的范围类是JDK 1.8引入的 java.time.temporal.ValueRange

ValueRange range = ValueRange.of(10, 20);

如上所述,我们通过static of()方法创建ValueRange对象。然后,我们使用每个对象的isValidIntValue()方法检查数字是否存在于每个范围内。

需要注意的是,ValueRange默认只支持闭区间检查。因此,为了验证左开区间,我们需要增加下限,对于右开区间,则需要减小上限,如上所示。

4.2. 使用Apache Commons

接下来,我们将使用第三方库中的范围类。首先,我们需要在项目中添加Apache Commons的依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>

这里,我们实现了与之前相同的行为,但使用了Apache Commons的Range类:

Range range = Range.between(10, 20);

就像使用ValueRangeof()方法一样,我们通过between()方法传递下限和上限来创建Range对象。然后,我们使用contains()方法检查数字是否存在于每个范围中。

Apache CommonsRange类也只支持闭区间,但我们再次调整了下限和上限,就像处理ValueRange一样。

此外,作为泛型类,Range不仅可以用于Integer,还可以用于任何实现了Comparable接口的其他类型。

4.3. 使用Google Guava

最后,我们在项目中添加Google Guava的依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
</dependency>

我们可以使用Guava的Range类重新实现之前的行为:

Range<Integer> range = Range.closedOpen(10, 20);

如上所示,Guava的Range类为之前讨论的所有范围类型提供了四个单独的创建方法。与我们之前看到的其他范围类不同,Guava的Range类原生支持开放和半开半闭区间。例如,要指定一个不包含上限的半开区间,我们使用closedOpen()方法传递下限和上限。对于不包含下限的半开区间,我们使用openClosed()。然后,我们使用contains()方法检查数字是否存在于每个范围内。

5. 总结

在这篇文章中,我们学习了如何使用基本运算符和范围类来检查整数是否在一个给定的范围内。我们也探讨了各种方法的优点和缺点。

如往常一样,这些示例的源代码可以在GitHub上找到。