Javaで文字列が数値かどうかを調べる
1前書き
_Stringを操作している間、
_
Stringが有効な数値かどうかを判断する必要があります。
-
このチュートリアルでは、与えられた
__String
__が数値** であるかどうかを検出する複数の方法を探ります。最初に普通のJavaを使い、次に正規表現を使い、最後に外部ライブラリを使います。
さまざまな実装についての説明が終わったら、ベンチマークを使用してどの方法が最適かを判断します。
メインコンテンツに進む前に、いくつかの前提条件から始めましょう。
2前提条件
この記事の後半では、Apache Commons外部ライブラリを使用します。この依存関係を含めるには、
pom.xml
に次の行を追加します。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
このライブラリの最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.apache.commons%22%20AND%20a%3A%22commons-lang3にあります。 %22[メイヴン中央]。
3プレーンJava
の使い方
おそらく、
__ String
__が数値かどうかを確認する最も簡単で信頼できる方法は、Javaの組み込みメソッドを使用して構文解析することです。
-
Integer.parseInt(String)
-
Float.parseFloat(String)
-
Double.parseDouble(String)
-
Long.parseLong(String)
-
new BigInteger(String)
これらのメソッドが
NumberFormatException
をスローしない場合、解析は成功し、
__ String
__is数値:
public static boolean isNumeric(String strNum) {
try {
double d = Double.parseDouble(strNum);
} catch (NumberFormatException | NullPointerException nfe) {
return false;
}
return true;
}
この方法を実際に見てみましょう。
assertThat(isNumeric("22")).isTrue();
assertThat(isNumeric("5.05")).isTrue();
assertThat(isNumeric("-200")).isTrue();
assertThat(isNumeric("10.0d")).isTrue();
assertThat(isNumeric(" 22 ")).isTrue();
assertThat(isNumeric(null)).isFalse();
assertThat(isNumeric("")).isFalse();
assertThat(isNumeric("abc")).isFalse();
_isNumeric()
メソッドでは、
Double
型の値をチェックしているだけですが、このメソッドは、先ほど紹介した解析メソッドのいずれかを使用して、
Integer
、
Float
、
Long
_
、および多数の値をチェックするように変更できます。
これらのメソッドは
Java文字列変換
の記事でも議論されています。
3.1.
Scanner
を使用した入力の確認
java.util
‘s
Scanner
クラスは、おそらく
int
、
double
などの基本タイプの入力を取得するためのプレーンJavaでの最も簡単な方法です。また、指定された入力が特定のタイプかどうかを検証するさまざまなAPIも提供します。
たとえば、** 次のAPIは、入力が整数型、long型、float型のいずれであるかを確認します。
-
scanner.hasNextInt()
-
scanner.hasNextLong()
-
scanner.hasNextFloat()
これらのAPIは、入力タイプに基づいて単純な
true
または
false
を返します。これらのAPIを使用して、次の入力が目的のタイプであることを確認できます。
次のスニペットは、入力が整数かどうかを確認します。
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("Enter an integer : ");
if (scanner.hasNextInt()) {
System.out.println("You entered : " + scanner.nextInt());
} else {
System.out.println("The input is not an integer");
}
}
同様に、他のAPIを使って他の型をチェックすることもできます。
4正規表現を使う
それでは、正規表現
__-?\ d +(\。\ d +)?
__を使って、数値と一致させることができます。
しかし、これは言うまでもありませんが、この正規表現を修正して広範囲のルールを識別して対処することができます。ここでは、単純にします。
この正規表現を分解して、それがどのように機能するのかを見てみましょう。
-
-?
– この部分は与えられた数が負であるかどうかを識別する、ダッシュ
“
–
”は文字通りダッシュを検索し、疑問符“
?
”はそのダッシュをマークします。
オプションとして存在
**
\ d +
– これは1桁以上の数字を検索します
-
(\。\ d)?
– 正規表現のこの部分は浮動小数点数を識別するためのものです。ここに
1桁以上の数字とそれに続くピリオドを検索しています。最後の疑問符は、この完全なグループがオプションであることを意味します。
正規表現は非常に広いトピックであり、簡単な概要を得るためにリンクを見てください:/regular-expressions-java[このリンクされたBaeldungの記事]。
今のところ、上記の正規表現を使ってメソッドを作成しましょう:
public static boolean isNumeric(String strNum) {
return strNum.matches("-?\\d+(\\.\\d+)?");
}
それでは、上記のメソッドに対するいくつかの主張を見てみましょう。
assertThat(isNumeric("22")).isTrue();
assertThat(isNumeric("5.05")).isTrue();
assertThat(isNumeric("-200")).isTrue();
assertThat(isNumeric("abc")).isFalse();
5. Apache Commonsを使う
このセクションでは、Apache Commonsライブラリで利用可能なさまざまな方法について説明します。
5.1.
NumberUtils.isCreatable(String)
Apache Commonsの
__https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html[NumberUtils]
は、静的メソッド
https://commons.apacheを提供します。
org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html#isCreatable-java.lang.String-[NumberUtils.isCreatable(String)]
これは
__有効なJava番号かそうではありません。
このメソッドは受け入れます:
-
0xまたは0Xで始まる16進数
-
先頭の0から始まる8進数
-
科学的記数法(例えば1.05e-10)
-
型修飾子でマークされた番号(1Lや2.2dなど)
提供された文字列が
__null
または
empty/blank
の場合、それは数値とは見なされず、この場合、このメソッドは
false
__を返します。
この方法でいくつかテストを実行しましょう。
assertThat(NumberUtils.isCreatable("22")).isTrue();
assertThat(NumberUtils.isCreatable("5.05")).isTrue();
assertThat(NumberUtils.isCreatable("-200")).isTrue();
assertThat(NumberUtils.isCreatable("10.0d")).isTrue();
assertThat(NumberUtils.isCreatable("1000L")).isTrue();
assertThat(NumberUtils.isCreatable("0xFF")).isTrue();
assertThat(NumberUtils.isCreatable("07")).isTrue();
assertThat(NumberUtils.isCreatable("2.99e+8")).isTrue();
assertThat(NumberUtils.isCreatable(null)).isFalse();
assertThat(NumberUtils.isCreatable("")).isFalse();
assertThat(NumberUtils.isCreatable("abc")).isFalse();
assertThat(NumberUtils.isCreatable(" 22 ")).isFalse();
assertThat(NumberUtils.isCreatable("09")).isFalse();
6行目、7行目、8行目に、それぞれ16進数、8進数、科学表記法について正しい____アサーションがあることに注意してください。
14行目でも、文字列
__“ 09”
は
false
を返します。これは、先行する
“ 0”
がこれが8進数であり、
“ 09”
__が有効な8進数ではないことを示しているためです。
このメソッドで
_true
を返す入力ごとに、https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html#createNumber-java.langを使用できます.String – [
NumberUtils.createNumber(String)_
]これで有効な番号がわかります。
5.2.
NumberUtils.isParsable(String)
__https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html#isParsable-java.lang.String-[NumberUtils.isParsable(String)]
メソッド与えられた
String
__が解析可能かどうかをチェックします。
-
解析可能な数値は、
Integer.parseInt(String)
、
Long.parseLong(String)
、
__Float.parseFloat(String)
または
Double.parseDouble(String)__のような任意の解析方法で正常に解析されたものです。
NumberUtils.isCreatable()
とは異なり、このメソッドは16進数、科学表記法、または型修飾子で終わる文字列、つまり
_ ‘f’、 ‘F’、 ‘d’、 ‘D’、 ‘l’または
L ‘._
いくつかの確約を見てみましょう:
assertThat(NumberUtils.isParsable("22")).isTrue();
assertThat(NumberUtils.isParsable("-23")).isTrue();
assertThat(NumberUtils.isParsable("2.2")).isTrue();
assertThat(NumberUtils.isParsable("09")).isTrue();
assertThat(NumberUtils.isParsable(null)).isFalse();
assertThat(NumberUtils.isParsable("")).isFalse();
assertThat(NumberUtils.isParsable("6.2f")).isFalse();
assertThat(NumberUtils.isParsable("9.8d")).isFalse();
assertThat(NumberUtils.isParsable("22L")).isFalse();
assertThat(NumberUtils.isParsable("0xFF")).isFalse();
assertThat(NumberUtils.isParsable("2.99e+8")).isFalse();
4行目では、
NumberUtils.isCreatable()
とは異なり、文字列____“ 0”で始まる数は8進数と見なされませんが、通常の10進数であるためtrueを返します。
このメソッドは、セクション3で行ったことの代わりとして使用できます。ここでは、数値を解析してエラーをチェックします。
5.3.
_StringUtils.isNumeric(CharSequence
)___
メソッド
__https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#isNumeric-java.lang.CharSequence-[StringUtils.isNumeric(CharSequence)]
__は厳密にチェックUnicode数字の場合これの意味は:
-
Unicodeの数字である任意の言語の任意の数字が許容されます
-
小数点はUnicodeの数字とは見なされないので、
有効
。先行符号(正または負)もまた許容されません。
では、このメソッドの動作を見てみましょう。
assertThat(StringUtils.isNumeric("123")).isTrue();
assertThat(StringUtils.isNumeric("١٢٣")).isTrue();
assertThat(StringUtils.isNumeric("१२३")).isTrue();
assertThat(StringUtils.isNumeric(null)).isFalse();
assertThat(StringUtils.isNumeric("")).isFalse();
assertThat(StringUtils.isNumeric(" ")).isFalse();
assertThat(StringUtils.isNumeric("12 3")).isFalse();
assertThat(StringUtils.isNumeric("ab2c")).isFalse();
assertThat(StringUtils.isNumeric("12.3")).isFalse();
assertThat(StringUtils.isNumeric("-123")).isFalse();
2行目と3行目の入力パラメータは、それぞれアラビア語とDevanagariの
__122で数値を表しています。これらは有効なUnicode数字なので、このメソッドはそれらに対して
true
__を返します。
5.4.
StringUtils.isNumericSpace(CharSequence)
StringUtils.isNumericSpace(CharSequence)
は厳密にチェックされます。 Unicodeの数字および/またはスペース用。これは
__StringUtils.isNumeric()
__と同じですが、先頭と末尾のスペースだけでなく、数字と数字の間にある場合にもスペースを使用できる点が異なります。
assertThat(StringUtils.isNumericSpace("123")).isTrue();
assertThat(StringUtils.isNumericSpace("١٢٣")).isTrue();
assertThat(StringUtils.isNumericSpace("")).isTrue();
assertThat(StringUtils.isNumericSpace(" ")).isTrue();
assertThat(StringUtils.isNumericSpace("12 3")).isTrue();
assertThat(StringUtils.isNumericSpace(null)).isFalse();
assertThat(StringUtils.isNumericSpace("ab2c")).isFalse();
assertThat(StringUtils.isNumericSpace("12.3")).isFalse();
assertThat(StringUtils.isNumericSpace("-123")).isFalse();
6. ベンチマーク
この記事を締めくくる前に、上記の方法のどれが最適なアプローチであるかを分析するのに役立つベンチマーク結果をすぐに確認しましょう。
Benchmark Mode Cnt Score Error Units
Benchmarking.usingCoreJava avgt 20 152.061 ± 24.300 ns/op
Benchmarking.usingRegularExpressions avgt 20 1299.258 ± 175.688 ns/op
Benchmarking.usingNumberUtils__isCreatable avgt 20 63.811 ± 5.638 ns/op
Benchmarking.usingNumberUtils__isParsable avgt 20 58.706 ± 5.299 ns/op
Benchmarking.usingStringUtils__isNumeric avgt 20 35.599 ± 8.498 ns/op
Benchmarking.usingStringUtils__isNumericSpace avgt 20 37.010 ± 4.394 ns/op
ご覧のとおり、最もコストのかかる操作は正規表現を使用し、その後にコアとなるJavaベースのソリューションを使用することです。 Apache Commonsライブラリを使用する他のすべての操作は、概して同じです。
7. 結論
この記事では、
__ String
__が数値かどうかを調べるためのさまざまな方法を調べました。私たちは両方の解決策 – 組み込みメソッドと外部ライブラリ – を調べました。
いつものように、ベンチマークを実行するために使用されるコードを含む上記のすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/java-strings[over on GitHub]で見つけることができます。