Zwykle używam następującego idiomu, aby sprawdzić, czy String można przekonwertować na liczbę całkowitą.
public boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
Czy to tylko ja, czy wydaje się to nieco hackerskie? Jaki jest lepszy sposób?
Zobacz moją odpowiedź (z wzorców, na podstawie wcześniejszej odpowiedzi przez CodingWithSpike ), aby zobaczyć, dlaczego mam odwrócić moją pozycję i zaakceptowane odpowiedź Jonas Klemming za tego problemu. Myślę, że ten oryginalny kod będzie używany przez większość ludzi, ponieważ jest szybszy do wdrożenia i łatwiejszy w utrzymaniu, ale jest o rząd wielkości wolniejszy, gdy dostarczane są dane niecałkowite.
Odpowiedzi:
Jeśli nie przejmujesz się potencjalnymi problemami z przepełnieniem, ta funkcja będzie działać około 20-30 razy szybciej niż przy użyciu
Integer.parseInt()
.źródło
Masz, ale powinieneś tylko złapać
NumberFormatException
.źródło
Zrobił szybki test porównawczy. Wyjątki nie są tak naprawdę kosztowne, chyba że zaczniesz wycofywać wiele metod, a JVM musi wykonać wiele pracy, aby ustawić stos wykonawczy. Pozostając w tej samej metodzie, nie są złymi wykonawcami.
Wynik:
Zgadzam się, że rozwiązanie Jonasa K. jest również najbardziej niezawodne. Wygląda na to, że wygrywa :)
źródło
^
i$
po raz drugi, ponieważ wmatches
cały ciąg musi odpowiadać regex (2),str.matches
za każdym razem będzie musiał stworzyć swój własnyPattern
, który jest kosztowny. Ze względu na wydajność powinniśmy utworzyć taki Wzorzec tylko raz poza tą metodą i użyć go wewnątrz. (3) Możemy również utworzyć tylko jeden obiekt Matcher i używać goreset(CharSequence)
do przekazywania danych użytkownika i zwracania jegomatches()
wyniku.private final Matcher m = Pattern.compile("-?\\d+").matcher(""); private boolean byRegex(String str) { return m.reset(str).matches(); }
powinno mieć lepszą wydajność.matches
jest dodawane^
i$
niejawnie. Spójrz na wynik" 123".matches("\\d+")
i"123".matches("\\d+")
. Zobaczyszfalse
itrue
.false
zostanie zwrócone, ponieważ ciąg zaczyna się od spacji, która uniemożliwia pełne dopasowanie wyrażenia regularnego.Ponieważ istnieje możliwość, że ludzie nadal będą tu odwiedzać i będą stronniczy w stosunku do Regex po testach porównawczych ... Więc dam zaktualizowaną wersję testu porównawczego, ze skompilowaną wersją Regex. To, w przeciwieństwie do poprzednich testów porównawczych, pokazuje, że rozwiązanie Regex ma niezmiennie dobrą wydajność.
Skopiowano z Billa jaszczurki i zaktualizowano do skompilowanej wersji:
Wyniki:
źródło
336
."^[+-]?\\d+$"
byłoby jeszcze lepiej.chociaż standardowa biblioteka Java naprawdę brakuje takich funkcji narzędziowych
Myślę, że Apache Commons to „must have” dla każdego programisty Java
szkoda, że nie jest jeszcze przeniesiony do Java5
źródło
Zależy to częściowo od tego, co rozumiesz przez „można przekonwertować na liczbę całkowitą”.
Jeśli masz na myśli „może zostać zamieniony na int w Javie”, to odpowiedź od Jonasa jest dobrym początkiem, ale nie do końca kończy pracę. Na przykład minie 999999999999999999999999999999 Dodałbym normalne wywołanie try / catch z twojego pytania na końcu metody.
Sprawdzanie znak po znaku skutecznie odrzuca przypadki „nie liczba całkowita”, pozostawiając „jest to liczba całkowita, ale Java nie może sobie z tym poradzić” przypadki, które mają zostać przechwycone przez wolniejszą trasę wyjątku. Możesz to zrobić trochę ręcznie, ale byłoby to wiele bardziej skomplikowane.
źródło
Tylko jeden komentarz na temat regexp. Każdy podany tutaj przykład jest błędny! Jeśli chcesz użyć wyrażenia regularnego, nie zapomnij, że skompilowanie wzorca zajmuje dużo czasu. To:
a także to:
powoduje kompilację wzorca w każdym wywołaniu metody. Aby używać go poprawnie, wykonaj następujące czynności:
źródło
Istnieje wersja guava:
Zwróci null zamiast zgłaszania wyjątku, jeśli nie uda się parsować łańcucha.
źródło
Skopiowałem kod z odpowiedzi rally25rs i dodałem kilka testów dla danych niecałkowitych. Wyniki są niezaprzeczalnie na korzyść metody opublikowanej przez Jonasa Klemminga. Wyniki dla metody wyjątku, którą pierwotnie opublikowałem, są całkiem dobre, gdy masz dane całkowite, ale są najgorsze, gdy nie masz, podczas gdy wyniki dla rozwiązania RegEx (założę się, że wiele osób korzysta) były konsekwentnie złe. Zobacz odpowiedź Felipe na skompilowany przykład wyrażenia regularnego, który jest znacznie szybszy.
Wyniki:
źródło
Jest to krótsze, ale krótsze niekoniecznie lepsze (i nie złapie wartości całkowitych, które są poza zakresem, jak wskazano w komentarzu danatela ):
Osobiście, ponieważ implementacja jest wyciskana metodą pomocniczą, a poprawność przewyższa długość, po prostu wybrałbym coś takiego, co masz (bez łapania
Exception
klasy podstawowej zamiastNumberFormatException
).źródło
Możesz użyć metody dopasowania klasy ciągów. [0-9] reprezentuje wszystkie wartości, jakie mogą być, + oznacza, że musi mieć co najmniej jeden znak, a * oznacza, że może mieć zero lub więcej znaków.
źródło
Co powiesz na:
źródło
To jest wariant Java 8 odpowiedzi Jonasa Klemminga:
Kod testowy:
Wyniki kodu testowego:
źródło
Wystarczy sprawdzić NumberFormatException : -
źródło
Jeśli tablica ciągów zawiera czyste liczby całkowite i ciągi, poniższy kod powinien działać. Musisz tylko spojrzeć na pierwszą postać. np. [„4”, „44”, „abc”, „77”, „bond”]
źródło
Możesz także użyć klasy Scanner i użyć hasNextInt () - a to pozwala na testowanie również innych typów, takich jak zmiennoprzecinkowe itp.
źródło
Jeśli chcesz sprawdzić, czy ciąg reprezentuje liczbę całkowitą pasującą do typu int, dokonałem niewielkiej modyfikacji odpowiedzi jonas, aby ciągi reprezentujące liczby całkowite większe niż Integer.MAX_VALUE lub mniejsze niż Integer.MIN_VALUE, teraz zwrócą fałszywe. Na przykład: „3147483647” zwróci fałsz, ponieważ 3147483647 jest większy niż 2147483647, i podobnie „-2147483649” również zwróci fałsz, ponieważ -2147483649 jest mniejszy niż -2147483648.
źródło
trim()
więc jest to wyraźnie celowy wybór projektu.Możesz wypróbować narzędzia Apache
Zobacz javadoc tutaj
źródło
isCreateable(String)
zamiast tego.Prawdopodobnie musisz również wziąć pod uwagę przypadek użycia:
Jeśli przez większość czasu spodziewasz się, że liczby będą prawidłowe, wyłapanie wyjątku powoduje jedynie narzut wydajności podczas próby konwersji nieprawidłowych liczb. Natomiast nazywając jakąś
isInteger()
metodę, a następnie przekonwertować używającInteger.parseInt()
będzie zawsze powodować narzut wydajności dla ważnych numerów - struny są analizowane dwa razy, raz przez sprawdzanie i raz przez konwersję.źródło
Jest to modyfikacja kodu Jonasa , który sprawdza, czy ciąg znaków znajduje się w zasięgu, aby można go było rzutować na liczbę całkowitą.
źródło
Jeśli używasz interfejsu API Androida, możesz użyć:
źródło
Inna opcja:
źródło
źródło
To, co zrobiłeś, działa, ale prawdopodobnie nie zawsze powinieneś to sprawdzać. Wyjątki dotyczące rzucania powinny być zarezerwowane dla „wyjątkowych” sytuacji (może to jednak pasuje do twojego przypadku) i są bardzo kosztowne pod względem wydajności.
źródło
źródło
Działa to tylko dla dodatnich liczb całkowitych.
źródło
To działa dla mnie. Wystarczy zidentyfikować, czy Łańcuch jest prymitywny czy liczba.
źródło
Aby sprawdzić wszystkie znaki int, możesz po prostu użyć podwójnego ujemnego.
if (! searchString.matches („[^ 0-9] + $”)) ...
[^ 0-9] + $ sprawdza, czy są jakieś znaki, które nie są liczbami całkowitymi, więc test nie powiedzie się, jeśli to prawda. Po prostu NIE, a osiągniesz sukces.
źródło
matches
Metoda mecze przeciwko cały ciąg, a nie tylko jego część.if
bloku. Nie powinno.Znajdź to może być pomocne:
źródło
Wierzę, że istnieje ryzyko zerowe uruchomiony w drodze wyjątku, bo jak widać poniżej wami bezpiecznie przetwarzać
int
doString
a nie na odwrót.Więc:
Państwo sprawdzić , czy każdy automat z charakterem w swoich meczów smyczkowych przynajmniej jeden ze znaków { „0”, „1”, „2”, „3”, „4”, „5”, „6”, „7”, „8”, „9”} .
Ci Podsumowując wszystkie czasy, że napotkane w gniazdach powyższe znaki.
Na koniec sprawdzasz, czy czasy, w których napotkałeś liczby całkowite jako znaki, są równe długości podanego ciągu.
W praktyce mamy:
A wyniki są następujące:
Podobnie, można zweryfikować, czy
String
jestfloat
czydouble
jednak w tych przypadkach trzeba spotkać tylko jeden. (kropka) w ciągu znaków i oczywiście sprawdź, czydigits == (aString.length()-1)
Mam nadzieję, że pomogłem
źródło