Обычно я использую следующую идиому, чтобы проверить, можно ли преобразовать строку в целое число.
public boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
Это только я, или это кажется немного хакерским? Какой способ лучше?
Смотрите мой ответ (с тестами, основанные на ранее ответ по CodingWithSpike ) , чтобы понять , почему я отменил свою позицию и принял ответ Jonas Klemming по этой проблеме. Я думаю, что этот оригинальный код будет использоваться большинством людей, потому что он быстрее реализуется и более удобен в обслуживании, но он на несколько порядков медленнее, когда предоставляются нецелые данные.
Ответы:
Если вас не беспокоят потенциальные проблемы переполнения, эта функция будет работать примерно в 20-30 раз быстрее, чем при использовании
Integer.parseInt()
.источник
У вас есть, но вы должны только поймать
NumberFormatException
.источник
Сделал быстрый тест. Исключения на самом деле не такие уж и дорогие, если только вы не начнете использовать несколько методов, а JVM придется проделать большую работу, чтобы установить стек выполнения. Оставаясь в том же методе, они не плохие исполнители.
Вывод:
Я согласен, что решение Jonas K является самым надежным. Похоже, он выигрывает :)
источник
^
и во$
второй раз , так как вmatches
целом строка должна соответствовать регулярному выражению, (2)str.matches
каждый раз , когда нужно будет создать свой собственный ,Pattern
который стоит дорого. Из соображений производительности мы должны создать такой шаблон только один раз за пределами этого метода и использовать его внутри. (3) Мы также можем создать только один объект Matcher и использовать егоreset(CharSequence)
для передачи пользовательских данных и возврата егоmatches()
результата.private final Matcher m = Pattern.compile("-?\\d+").matcher(""); private boolean byRegex(String str) { return m.reset(str).matches(); }
должно иметь лучшую производительность.matches
как добавляется^
и$
неявно. Посмотрите на результат" 123".matches("\\d+")
и"123".matches("\\d+")
. Вы увидитеfalse
иtrue
.false
будет возвращено, потому что строка начинается с пробела, который не позволяет ей полностью соответствовать регулярному выражению.Так как есть вероятность, что люди все еще посещают здесь и будут смещены против Regex после тестов ... Так что я собираюсь дать обновленную версию теста с скомпилированной версией Regex. В отличие от предыдущих тестов, этот пример показывает, что решение Regex стабильно имеет хорошую производительность.
Скопировано из Билла Ящера и дополнено скомпилированной версией:
Полученные результаты:
источник
336
."^[+-]?\\d+$"
, будет еще лучше.хотя стандартная библиотека Java действительно пропускает такие вспомогательные функции
Я думаю, что Apache Commons является обязательным условием для каждого Java-программиста
Жаль, что он еще не портирован на Java5
источник
Отчасти это зависит от того, что вы подразумеваете под «можно преобразовать в целое число».
Если вы имеете в виду «может быть преобразован в int в Java», то ответ от Jonas - хорошее начало, но не совсем завершает работу. Например, он пройдет 999999999999999999999999999999. Я бы добавил нормальный вызов try / catch из вашего собственного вопроса в конце метода.
Посимвольные проверки будут эффективно отклонять «не целое число» случаев, оставляя «это целое число, но Java не может его обработать», чтобы случаи были обнаружены более медленным маршрутом исключения. Вы можете сделать это немного вручную, но это будет намного сложнее.
источник
Только один комментарий о регулярном выражении. Каждый приведенный здесь пример неверен! Если вы хотите использовать регулярные выражения, не забывайте, что компиляция шаблона занимает много времени. Это:
а также это:
вызывает компиляцию шаблона в каждом вызове метода. Чтобы правильно его использовать следуйте:
источник
Есть версия гуавы:
Он вернет ноль вместо генерации исключения, если ему не удастся проанализировать строку.
источник
Я скопировал код из ответа rally25rs и добавил несколько тестов для нецелых данных. Результаты неоспоримо в пользу метода , публикуемую Йонас Klemming. Результаты для метода Exception, который я первоначально опубликовал, довольно хороши, когда у вас есть целочисленные данные, но они хуже, когда у вас их нет, в то время как результаты для решения RegEx (которые, я уверен, многие используют) были постоянно плохими. Смотрите ответ Фелипе для скомпилированного примера регулярных выражений, который намного быстрее.
Полученные результаты:
источник
Это короче, но короче не обязательно лучше (и оно не будет отлавливать целочисленные значения, выходящие за пределы диапазона, как указано в комментарии danatel ):
Лично, поскольку реализация спекулируется в вспомогательном методе, а правильность бьет по длине, я бы просто пошел с чем-то вроде того, что у вас есть (минус перехват базового
Exception
класса, а неNumberFormatException
).источник
Вы можете использовать метод совпадений строкового класса. [0-9] представляет все возможные значения, + означает, что длина должна быть не менее одного символа, а * означает, что длина может быть равна нулю или более.
источник
Как насчет:
источник
Это вариант ответа Jonas Klemming на Java 8:
Тестовый код:
Результаты теста кода:
источник
Вы просто проверяете NumberFormatException : -
источник
Если ваш массив String содержит чистые целые числа и строки, код ниже должен работать. Вам нужно только взглянуть на первого персонажа. например, ["4", "44", "abc", "77", "bond"]
источник
Вы также можете использовать класс Scanner и использовать hasNextInt () - и это позволяет вам проверять и другие типы, такие как float и т. Д.
источник
Если вы хотите проверить, представляет ли строка целое число, которое соответствует типу int, я немного изменил ответ jonas, чтобы строки, представляющие целые числа, большие, чем Integer.MAX_VALUE, или меньше, чем Integer.MIN_VALUE, теперь возвращали ложный. Например: «3147483647» вернет false, потому что 3147483647 больше, чем 2147483647, и аналогично «-2147483649» также вернет false, потому что -2147483649 меньше, чем -2147483648.
источник
trim()
так что это явно преднамеренный выбор дизайна.Вы можете попробовать утилиты apache
Смотрите Javadoc здесь
источник
isCreateable(String)
вместо этого.Вы, вероятно, должны принять во внимание также вариант использования:
Если большую часть времени вы ожидаете, что числа будут действительными, то перехват исключения приводит только к снижению производительности при попытке преобразовать недопустимые числа. Принимая во внимание , вызывая некоторый
isInteger()
метод , а затем преобразовать , используяInteger.parseInt()
будет всегда причиной над головой производительности для действительных чисел - строки обрабатываются дважды, один раз чек и один раз преобразования.источник
Это модификация кода Джонаса , который проверяет, находится ли строка в пределах диапазона, который будет приведен к целому числу.
источник
Если вы используете Android API, вы можете использовать:
источник
Другой вариант:
источник
источник
То, что вы сделали, работает, но вы, вероятно, не всегда должны проверять это. Броски исключений должны быть зарезервированы для «исключительных» ситуаций (возможно, это подходит для вашего случая), и они очень дороги с точки зрения производительности.
источник
источник
Это будет работать только для натуральных чисел.
источник
Это работает для меня. Просто чтобы определить, является ли String примитивом или числом.
источник
Чтобы проверить все int-символы, вы можете просто использовать двойной минус.
if (! searchString.matches ("[^ 0-9] + $")) ...
[^ 0-9] + $ проверяет, есть ли какие-либо символы, которые не являются целочисленными, поэтому проверка завершается неудачно, если это правда. Просто НЕ это, и вы получите успех.
источник
matches
Метод соответствует против всей строки, а не только часть его.if
блок. Это не должноНайти это может быть полезным:
источник
Я полагаю , что есть нулевой риск нарваться исключение, потому что , как вы можете видеть ниже , Вы всегда безопасно разобрать ,
int
чтобыString
и не наоборот.Так:
Вы проверяете, соответствует ли каждый слот символа в вашей строке хотя бы одному из символов {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} .
Вы суммируете все времена, которые встречали в слотах вышеперечисленных символов.
И, наконец, вы проверяете, совпадает ли время, в которое вы встречали целые числа как символы, с длиной заданной строки.
И на практике имеем:
И результаты:
Точно так же вы можете проверить,
String
является ли afloat
или a,double
но в этих случаях вам нужно встретиться только с одним. (точка) в строке и, конечно, проверьте, еслиdigits == (aString.length()-1)
Надеюсь я помог
источник