Normalerweise verwende ich die folgende Redewendung, um zu überprüfen, ob ein String in eine Ganzzahl konvertiert werden kann.
public boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
Ist es nur ich oder scheint das ein bisschen hackisch? Was ist ein besserer Weg?
In meiner Antwort (mit Benchmarks, basierend auf der früheren Antwort von CodingWithSpike ) erfahren Sie , warum ich meine Position umgekehrt und Jonas Klemmings Antwort auf dieses Problem akzeptiert habe . Ich denke, dieser ursprüngliche Code wird von den meisten Leuten verwendet, weil er schneller zu implementieren und wartbarer ist, aber um Größenordnungen langsamer, wenn nicht ganzzahlige Daten bereitgestellt werden.
Antworten:
Wenn Sie sich nicht mit möglichen Überlaufproblemen befassen, wird diese Funktion etwa 20 bis 30 Mal schneller ausgeführt als die Verwendung
Integer.parseInt()
.quelle
Sie haben es, aber Sie sollten nur fangen
NumberFormatException
.quelle
Habe einen schnellen Benchmark gemacht. Ausnahmen sind eigentlich nicht so teuer, es sei denn, Sie beginnen, mehrere Methoden zurückzusetzen, und die JVM muss viel Arbeit leisten, um den Ausführungsstapel einzurichten. Wenn sie in der gleichen Methode bleiben, sind sie keine schlechten Darsteller.
Ausgabe:
Ich stimme zu, dass die Lösung von Jonas K auch die robusteste ist. Sieht aus wie er gewinnt :)
quelle
^
und$
zweites Mal inmatches
gesamter Zeichenfolge muss Regex Übereinstimmen, (2)str.matches
jedes Mal wird seine eigenen erstellen ,Pattern
die teuer ist. Aus Leistungsgründen sollten wir ein solches Muster nur einmal außerhalb dieser Methode erstellen und innerhalb verwenden. (3) Wir können auch nur ein Matcher-Objekt erstellen und es verwendenreset(CharSequence)
, um Benutzerdaten zu übergeben und dasmatches()
Ergebnis zurückzugeben.private final Matcher m = Pattern.compile("-?\\d+").matcher(""); private boolean byRegex(String str) { return m.reset(str).matches(); }
sollte eine bessere Leistung haben.matches
es hinzugefügt wird^
und$
implizit. Schauen Sie sich das Ergebnis von" 123".matches("\\d+")
und an"123".matches("\\d+")
. Du wirst sehenfalse
undtrue
.false
wird zurückgegeben, da die Zeichenfolge mit einem Leerzeichen beginnt, das verhindert, dass sie vollständig mit dem regulären Ausdruck übereinstimmt.Da es die Möglichkeit gibt, dass die Leute immer noch hierher kommen und nach den Benchmarks gegen Regex voreingenommen sind ... Also werde ich eine aktualisierte Version des Benchmarks mit einer kompilierten Version des Regex geben. Was im Gegensatz zu den vorherigen Benchmarks zeigt, dass die Regex-Lösung tatsächlich eine konstant gute Leistung aufweist.
Von Bill the Lizard kopiert und mit der kompilierten Version aktualisiert:
Ergebnisse:
quelle
336
."^[+-]?\\d+$"
wäre es sogar noch besser.obwohl Javas Standardbibliothek solche Dienstprogrammfunktionen wirklich vermisst
Ich denke, dass Apache Commons ein "Muss" für jeden Java-Programmierer ist
Schade, dass es noch nicht auf Java5 portiert ist
quelle
Dies hängt teilweise davon ab, was Sie unter "kann in eine Ganzzahl konvertiert werden" verstehen.
Wenn Sie meinen "kann in Java in ein int konvertiert werden", dann ist die Antwort von Jonas ein guter Anfang, aber beendet den Job nicht ganz. Es würde zum Beispiel 99999999999999999999999999999999 passieren. Ich würde den normalen Try / Catch-Aufruf aus Ihrer eigenen Frage am Ende der Methode hinzufügen.
Bei den zeichenweisen Überprüfungen werden Fälle "überhaupt keine Ganzzahl" effizient zurückgewiesen, sodass "es ist eine Ganzzahl, aber Java kann sie nicht verarbeiten" -Fälle von der langsameren Ausnahmeroute abgefangen werden. Sie könnten dies auch von Hand tun, aber es wäre viel komplizierter.
quelle
Nur ein Kommentar zu Regexp. Jedes hier angegebene Beispiel ist falsch!. Wenn Sie Regexp verwenden möchten, vergessen Sie nicht, dass das Kompilieren des Musters viel Zeit in Anspruch nimmt. Dies:
und auch das:
bewirkt bei jedem Methodenaufruf eine Kompilierung des Musters. Um es richtig zu verwenden, folgen Sie:
quelle
Es gibt eine Guavenversion:
Es wird null zurückgegeben, anstatt eine Ausnahme auszulösen, wenn die Zeichenfolge nicht analysiert werden kann.
quelle
Ich habe den Code aus der Antwort von Rally25 kopiert und einige Tests für nicht ganzzahlige Daten hinzugefügt. Die Ergebnisse sprechen zweifellos für die von Jonas Klemming veröffentlichte Methode. Die Ergebnisse für die Ausnahmemethode, die ich ursprünglich veröffentlicht habe, sind ziemlich gut, wenn Sie ganzzahlige Daten haben, aber sie sind die schlechtesten, wenn Sie dies nicht tun, während die Ergebnisse für die RegEx-Lösung (auf die ich wetten werde, dass viele Leute sie verwenden) waren durchweg schlecht. In Felipes Antwort finden Sie ein kompiliertes Regex-Beispiel, das viel schneller ist.
Ergebnisse:
quelle
Dies ist kürzer, aber kürzer ist nicht unbedingt besser (und es werden keine ganzzahligen Werte erfasst, die außerhalb des Bereichs liegen, wie in Danatels Kommentar ausgeführt ):
Persönlich würde ich, da die Implementierung in einer Hilfsmethode weggezerrt ist und die Korrektheit die Länge übertrumpft, einfach so etwas wie das machen, was Sie haben (abzüglich des Abfangens der Basisklasse
Exception
anstattNumberFormatException
).quelle
Sie können die Übereinstimmungsmethode der Zeichenfolgenklasse verwenden. Das [0-9] repräsentiert alle Werte, die es sein kann, das + bedeutet, dass es mindestens ein Zeichen lang sein muss, und das * bedeutet, dass es null oder mehr Zeichen lang sein kann.
quelle
Wie wäre es mit:
quelle
Dies ist eine Java 8-Variante der Antwort von Jonas Klemming:
Testcode:
Ergebnisse des Testcodes:
quelle
Sie überprüfen nur NumberFormatException : -
quelle
Wenn Ihr String-Array reine Ganzzahlen und Strings enthält, sollte der folgende Code funktionieren. Sie müssen nur das erste Zeichen betrachten. zB ["4", "44", "abc", "77", "bond"]
quelle
Sie können auch die Scanner- Klasse und hasNextInt () verwenden. Auf diese Weise können Sie auch andere Typen wie Floats usw. testen.
quelle
Wenn Sie überprüfen möchten, ob die Zeichenfolge eine Ganzzahl darstellt, die in einen int-Typ passt, habe ich die Antwort der Jonas geringfügig geändert, sodass Zeichenfolgen, die Ganzzahlen darstellen, die größer als Integer.MAX_VALUE oder kleiner als Integer.MIN_VALUE sind, jetzt zurückgegeben werden falsch. Beispiel: "3147483647" gibt false zurück, da 3147483647 größer als 2147483647 ist, und "-2147483649" gibt ebenfalls false zurück, da -2147483649 kleiner als -2147483648 ist.
quelle
trim()
so dass dies eindeutig eine absichtliche Designentscheidung ist.Sie können Apache-Utils ausprobieren
Sehen Sie den Javadoc hier
quelle
isCreateable(String)
stattdessen verwenden.Sie müssen wahrscheinlich auch den Anwendungsfall berücksichtigen:
Wenn Sie die meiste Zeit erwarten, dass Zahlen gültig sind, verursacht das Abfangen der Ausnahme nur dann einen Leistungsaufwand, wenn Sie versuchen, ungültige Zahlen zu konvertieren. Während einige Aufruf
isInteger()
Methode und wandeln dann unter VerwendungInteger.parseInt()
wird immer für gültige Zahlen Ursache einer Leistungsaufwand - die Saiten zweimal analysiert werden, einmal durch die Prüfung und einmal durch die Umwandlung.quelle
Dies ist eine Modifikation von Jonas 'Code, die prüft, ob sich die Zeichenfolge innerhalb des Bereichs befindet, der in eine Ganzzahl umgewandelt werden soll.
quelle
Wenn Sie die Android-API verwenden, können Sie Folgendes verwenden:
quelle
Andere Option:
quelle
quelle
Was Sie getan haben, funktioniert, aber Sie sollten es wahrscheinlich nicht immer so überprüfen. Das Auslösen von Ausnahmen sollte "außergewöhnlichen" Situationen vorbehalten sein (möglicherweise passt dies jedoch in Ihren Fall) und ist in Bezug auf die Leistung sehr kostspielig.
quelle
quelle
Dies würde nur für positive ganze Zahlen funktionieren.
quelle
Das funktioniert bei mir. Einfach identifizieren, ob ein String ein Grundelement oder eine Zahl ist.
quelle
Um nach allen int-Zeichen zu suchen, können Sie einfach ein doppeltes Negativ verwenden.
if (! searchString.matches ("[^ 0-9] + $")) ...
[^ 0-9] + $ prüft, ob es Zeichen gibt, die nicht ganzzahlig sind. Daher schlägt der Test fehl, wenn er wahr ist. Nur NICHT das und du wirst wahr beim Erfolg.
quelle
matches
Methode stimmt mit der gesamten Zeichenfolge überein, nicht nur mit einem Teil davon.if
Block. Es sollte nicht.Finden Sie dies kann hilfreich sein:
quelle
Ich glaube , dass es Null - Risiko in eine Ausnahme ausgeführt wird , weil , wie Sie unten sehen Sie können immer sicher analysieren
int
zuString
und nicht umgekehrt.So:
Sie überprüfen, ob jeder Zeichenschlitz in Ihrer Zeichenfolge mit mindestens einem der Zeichen {"0", "1", "2", "3", "4", "5", "6", "7", übereinstimmt. "8", "9"} .
Sie summieren alle Zeiten, die Sie in den Slots auf die oben genannten Zeichen gestoßen sind.
Und schließlich überprüfen Sie , ob die Zeiten, zu denen Sie auf Ganzzahlen als Zeichen gestoßen sind, der Länge der angegebenen Zeichenfolge entsprechen.
Und in der Praxis haben wir:
Und die Ergebnisse sind:
Ebenso können Sie überprüfen, ob a
String
einfloat
oder ein ist,double
aber in diesen Fällen müssen Sie nur auf eines stoßen . (Punkt) in der Zeichenfolge und natürlich prüfen, obdigits == (aString.length()-1)
ich hoffe ich habe geholfen
quelle