一、概述
在本教程中,我们将研究一些方法来检查给定范围内是否存在整数。我们将使用运算符以及几个实用程序类来做到这一点。
2. 范围类型
在我们使用任何这些方法之前,我们必须清楚我们在谈论什么样的范围。在本教程中,我们将重点关注这四种有界范围类型:
封闭范围-包括其下限和上限
开放范围——不包括其下限和上限
左开右闭范围——包括其上限,不包括其下限
左闭右开范围——包括它的下限,不包括它的上限
例如,假设我们想知道整数20 是否出现在这两个范围内:R1 = [10, 2o)
,左闭右开范围,和R2 = (10, 20]
,左开右-封闭范围。由于R1
不包含其上限,因此整数20 仅存在于R2
中。
3. 使用<
和<=
运算符
我们的目标是确定一个数字是否在给定的下限和上限之间。我们将首先使用基本的Java 运算符对此进行检查。
让我们定义一个类来检查所有四种范围:
public class IntRangeOperators {
public static boolean isInClosedRange(Integer number, Integer lowerBound, Integer upperBound) {
return (lowerBound <= number && number <= upperBound);
}
public static boolean isInOpenRange(Integer number, Integer lowerBound, Integer upperBound) {
return (lowerBound < number && number < upperBound);
}
public static boolean isInOpenClosedRange(Integer number, Integer lowerBound, Integer upperBound) {
return (lowerBound < number && number <= upperBound);
}
public static boolean isInClosedOpenRange(Integer number, Integer lowerBound, Integer upperBound) {
return (lowerBound <= number && number < upperBound);
}
}
在这里,通过更改运算符以包含或排除边界,我们可以将区间调整为开放、封闭或半开放。
让我们测试一下我们的static
isInOpenClosedRange()
方法。我们将通过传入10 作为下限和20 作为上限来指定左开右闭范围(10,20]
:
assertTrue(IntRangeClassic.isInOpenClosedRange(20, 10, 20));
assertFalse(IntRangeClassic.isInOpenClosedRange(10, 10, 20));
在我们的第一个测试中,我们成功地验证了整数20 存在于(10,20]
范围内,包括其上界。然后我们确认整数10 不存在于同一范围内,不包括其下界。
4. 使用范围类
作为使用Java 运算符的替代方法,我们还可以使用表示范围的实用程序类。使用预定义类的主要好处是范围类为上述部分或全部范围类型提供了开箱即用的实现。
此外,我们可以使用我们定义的边界配置范围对象,并在其他方法或类中重用该对象。通过一次定义范围,如果我们需要对整个代码库中的同一范围进行多次检查,我们的代码就不容易出错。
另一方面,我们将在下面看到的两个范围类位于外部库中,必须先将其导入到我们的项目中,然后才能使用它们。
4.1。使用java.time.temporal.ValueRange
不需要导入外部库的范围类是java.time.temporal.ValueRange
,在JDK 1.8 中引入:
public class IntRangeValueRange {
public boolean isInClosedRange(Integer number, Integer lowerBound, Integer upperBound) {
final ValueRange range = ValueRange.of(lowerBound, upperBound);
return range.isValidIntValue(number);
}
public boolean isInOpenRange(Integer number, Integer lowerBound, Integer upperBound) {
final ValueRange range = ValueRange.of(lowerBound + 1, upperBound - 1);
return range.isValidIntValue(number);
}
public boolean isInOpenClosedRange(Integer number, Integer lowerBound, Integer upperBound) {
final ValueRange range = ValueRange.of(lowerBound + 1, upperBound);
return range.isValidIntValue(number);
}
public boolean isInClosedOpenRange(Integer number, Integer lowerBound, Integer upperBound) {
final ValueRange range = ValueRange.of(lowerBound, upperBound - 1);
return range.isValidIntValue(number);
}
}
正如我们在上面看到的,我们通过将lowerBound
和upperBound
传递给static
of()
方法来创建ValueRange
对象。然后,我们使用每个对象的isValidIntValue()
方法检查每个范围内是否存在number
。
我们应该注意到**ValueRange
仅支持开箱即用的封闭范围检查。正因为如此,我们必须通过增加lowerBound
来验证左开范围,通过减少upperBound
来验证右开范围**,就像我们上面所做的那样。
4.2.使用Apache Commons
让我们继续讨论一些可以从第三方库中使用的范围类。首先,我们将Apache Commons依赖项添加到我们的项目中:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
在这里,我们实现了与以前相同的行为,但使用了Apache CommonsRange
类:
public class IntRangeApacheCommons {
public boolean isInClosedRange(Integer number, Integer lowerBound, Integer upperBound) {
final Range<Integer> range = Range.between(lowerBound, upperBound);
return range.contains(number);
}
public boolean isInOpenRange(Integer number, Integer lowerBound, Integer upperBound) {
final Range<Integer> range = Range.between(lowerBound + 1, upperBound - 1);
return range.contains(number);
}
public boolean isInOpenClosedRange(Integer number, Integer lowerBound, Integer upperBound) {
final Range<Integer> range = Range.between(lowerBound + 1, upperBound);
return range.contains(number);
}
public boolean isInClosedOpenRange(Integer number, Integer lowerBound, Integer upperBound) {
final Range<Integer> range = Range.between(lowerBound, upperBound - 1);
return range.contains(number);
}
}
与ValueRange
的of()
方法一样,我们将lowerBound
和upperBound
传递给Range
的static between()
方法来创建Range
对象。然后我们使用contains()
方法检查number
是否存在于每个对象的范围内。
Apache CommonsRange
类也只支持封闭区间,但我们只是再次调整了lowerBound
和upperBound
,就像我们对ValueRange
所做的那样。
此外,作为一个泛型类,Range
不仅可以用于Integer
,还可以用于实现Comparable.
4.3.使用谷歌番石榴
最后,让我们将Google Guava依赖添加到我们的项目中:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
我们可以使用Guava 的Range
类重新实现与以前相同的行为:
public class IntRangeGoogleGuava {
public boolean isInClosedRange(Integer number, Integer lowerBound, Integer upperBound) {
final Range<Integer> range = Range.closed(lowerBound, upperBound);
return range.contains(number);
}
public boolean isInOpenRange(Integer number, Integer lowerBound, Integer upperBound) {
final Range<Integer> range = Range.open(lowerBound, upperBound);
return range.contains(number);
}
public boolean isInOpenClosedRange(Integer number, Integer lowerBound, Integer upperBound) {
final Range<Integer> range = Range.openClosed(lowerBound, upperBound);
return range.contains(number);
}
public boolean isInClosedOpenRange(Integer number, Integer lowerBound, Integer upperBound) {
final Range<Integer> range = Range.closedOpen(lowerBound, upperBound);
return range.contains(number);
}
}
我们可以在上面看到Guava 的Range
类有四个单独的方法来创建我们之前讨论的每种范围类型。也就是说,与我们目前看到的其他范围类不同,Guava 的Range
类本身支持开放和半开放范围。例如,要指定一个不包括其上限的半开区间,我们将lowerBound
和upperBound
传递给static
closedOpen()
方法。对于不包括其下限的半开区间,我们使用openClosed()
。然后我们使用contains()
方法检查每个范围内是否存在number
。
5. 结论
在本文中,我们学习了如何使用基本运算符和范围类来检查整数是否在给定范围内。我们还探讨了各种方法的优缺点。
0 评论