如何用Java檢查一個整數是否存在於一個範圍內
一、概述
在本教程中,我們將研究一些方法來檢查給定範圍內是否存在整數。我們將使用運算符以及幾個實用程序類來做到這一點。
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 Commons Range
類:
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 Commons Range
類也只支持封閉區間,但我們只是再次調整了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. 結論
在本文中,我們學習瞭如何使用基本運算符和範圍類來檢查整數是否在給定範圍內。我們還探討了各種方法的優缺點。
與往常一樣,這些示例的源代碼可在 GitHub 上獲得。