Какой лучший способ проверить, представляет ли String целое число в Java?


214

Обычно я использую следующую идиому, чтобы проверить, можно ли преобразовать строку в целое число.

public boolean isInteger( String input ) {
    try {
        Integer.parseInt( input );
        return true;
    }
    catch( Exception e ) {
        return false;
    }
}

Это только я, или это кажется немного хакерским? Какой способ лучше?


Смотрите мой ответ (с тестами, основанные на ранее ответ по CodingWithSpike ) , чтобы понять , почему я отменил свою позицию и принял ответ Jonas Klemming по этой проблеме. Я думаю, что этот оригинальный код будет использоваться большинством людей, потому что он быстрее реализуется и более удобен в обслуживании, но он на несколько порядков медленнее, когда предоставляются нецелые данные.


Что вы думаете о RegExp для решения?
Акшай Петани

Ответы:


171

Если вас не беспокоят потенциальные проблемы переполнения, эта функция будет работать примерно в 20-30 раз быстрее, чем при использовании Integer.parseInt().

public static boolean isInteger(String str) {
    if (str == null) {
        return false;
    }
    int length = str.length();
    if (length == 0) {
        return false;
    }
    int i = 0;
    if (str.charAt(0) == '-') {
        if (length == 1) {
            return false;
        }
        i = 1;
    }
    for (; i < length; i++) {
        char c = str.charAt(i);
        if (c < '0' || c > '9') {
            return false;
        }
    }
    return true;
}

50
(c <= '/' || c> = ':') выглядит немного странно. Я бы использовал (c <'0' || c> '9') ... быстрее ли операторы <= и> = в Java?
Аноним

3
Почему бы не использовать регулярные выражения? Не возвращает ли str.matches ("^ -? \\ d + $") идентичный коду выше.
Маглоб

15
Я бы использовал этот метод или оригинальный метод из вопроса до регулярного выражения. Это для производительности, оригинальный метод для скорости реализации и абсолютной ремонтопригодности. Решение для регулярных выражений не имеет к этому никакого отношения.
Билл Ящерица

4
Я беспокоюсь о переполнении, но этот метод может быть адаптирован для BigInts и все же быть намного быстрее, чем другие методы. Если кому-то интересно, почему я прикладываю столько усилий для решения такой простой проблемы, я создаю библиотеку, которая поможет решить проблемы Project Euler.
Билл Ящерица

1
Если вас беспокоит, можете ли вы на самом деле разобрать строку в int или long, вам также необходимо проверить, соответствует ли целое число, которое представляет строка, этим типам данных.
Джонас К

65

У вас есть, но вы должны только поймать NumberFormatException.


7
Да, считается плохой формой ловить больше исключений, чем нужно.
Крис

Ты прав. NFE - единственный, кого можно бросить, но это все еще плохая привычка.
Билл Ящерица

Я думаю, что NPE может быть сгенерирован, если input имеет значение null, поэтому ваш метод, вероятно, должен обрабатывать это явно, в зависимости от того, что вы хотите.
Дов Вассерман

@Dov: Вы правы, NPE и NFE должны быть явно пойманы.
Билл Ящерица

Этот ответ должен быть верным ответом на этот вопрос.
Breedly

40

Сделал быстрый тест. Исключения на самом деле не такие уж и дорогие, если только вы не начнете использовать несколько методов, а JVM придется проделать большую работу, чтобы установить стек выполнения. Оставаясь в том же методе, они не плохие исполнители.

 public void RunTests()
 {
     String str = "1234567890";

     long startTime = System.currentTimeMillis();
     for(int i = 0; i < 100000; i++)
         IsInt_ByException(str);
     long endTime = System.currentTimeMillis();
     System.out.print("ByException: ");
     System.out.println(endTime - startTime);

     startTime = System.currentTimeMillis();
     for(int i = 0; i < 100000; i++)
         IsInt_ByRegex(str);
     endTime = System.currentTimeMillis();
     System.out.print("ByRegex: ");
     System.out.println(endTime - startTime);

     startTime = System.currentTimeMillis();
     for(int i = 0; i < 100000; i++)
         IsInt_ByJonas(str);
     endTime = System.currentTimeMillis();
     System.out.print("ByJonas: ");
     System.out.println(endTime - startTime);
 }

 private boolean IsInt_ByException(String str)
 {
     try
     {
         Integer.parseInt(str);
         return true;
     }
     catch(NumberFormatException nfe)
     {
         return false;
     }
 }

 private boolean IsInt_ByRegex(String str)
 {
     return str.matches("^-?\\d+$");
 }

 public boolean IsInt_ByJonas(String str)
 {
     if (str == null) {
             return false;
     }
     int length = str.length();
     if (length == 0) {
             return false;
     }
     int i = 0;
     if (str.charAt(0) == '-') {
             if (length == 1) {
                     return false;
             }
             i = 1;
     }
     for (; i < length; i++) {
             char c = str.charAt(i);
             if (c <= '/' || c >= ':') {
                     return false;
             }
     }
     return true;
 }

Вывод:

ByException: 31

ByRegex: 453 (примечание: каждый раз перекомпилировать шаблон)

ByJonas: 16

Я согласен, что решение Jonas K является самым надежным. Похоже, он выигрывает :)


13
Отличная идея для сравнения всех трех. Чтобы быть справедливым по отношению к методам Regex и Jonas, вы должны тестировать с нецелочисленными строками, поскольку именно здесь метод Integer.parseInt будет действительно замедляться.
Билл Ящерица

4
Извините, но этот тест на регулярные выражения не очень хорош. (1) Вам не нужно , чтобы сделать регулярное выражение проверки двигателя для ^и во $второй раз , так как в 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(); }должно иметь лучшую производительность.
Пшемо

@Pshemo Integer.valueOf ("1") и Integer.valueOf ("1") выдают исключение, поэтому проверка на ^ и $ кажется разумной.
cquezel

1
@cquezel Да, но это не обязательно, так matchesкак добавляется ^и $неявно. Посмотрите на результат " 123".matches("\\d+")и "123".matches("\\d+"). Вы увидите falseи true. falseбудет возвращено, потому что строка начинается с пробела, который не позволяет ей полностью соответствовать регулярному выражению.
Пшемо

37

Так как есть вероятность, что люди все еще посещают здесь и будут смещены против Regex после тестов ... Так что я собираюсь дать обновленную версию теста с скомпилированной версией Regex. В отличие от предыдущих тестов, этот пример показывает, что решение Regex стабильно имеет хорошую производительность.

Скопировано из Билла Ящера и дополнено скомпилированной версией:

private final Pattern pattern = Pattern.compile("^-?\\d+$");

public void runTests() {
    String big_int = "1234567890";
    String non_int = "1234XY7890";

    long startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByException(big_int);
    long endTime = System.currentTimeMillis();
    System.out.print("ByException - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByException(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByException - non-integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByRegex(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByRegex - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByRegex(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByRegex - non-integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++)
            IsInt_ByCompiledRegex(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByCompiledRegex - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++)
            IsInt_ByCompiledRegex(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByCompiledRegex - non-integer data: ");
    System.out.println(endTime - startTime);


    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByJonas(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByJonas - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByJonas(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByJonas - non-integer data: ");
    System.out.println(endTime - startTime);
}

private boolean IsInt_ByException(String str)
{
    try
    {
        Integer.parseInt(str);
        return true;
    }
    catch(NumberFormatException nfe)
    {
        return false;
    }
}

private boolean IsInt_ByRegex(String str)
{
    return str.matches("^-?\\d+$");
}

private boolean IsInt_ByCompiledRegex(String str) {
    return pattern.matcher(str).find();
}

public boolean IsInt_ByJonas(String str)
{
    if (str == null) {
            return false;
    }
    int length = str.length();
    if (length == 0) {
            return false;
    }
    int i = 0;
    if (str.charAt(0) == '-') {
            if (length == 1) {
                    return false;
            }
            i = 1;
    }
    for (; i < length; i++) {
            char c = str.charAt(i);
            if (c <= '/' || c >= ':') {
                    return false;
            }
    }
    return true;
}

Полученные результаты:

ByException - integer data: 45
ByException - non-integer data: 465

ByRegex - integer data: 272
ByRegex - non-integer data: 131

ByCompiledRegex - integer data: 45
ByCompiledRegex - non-integer data: 26

ByJonas - integer data: 8
ByJonas - non-integer data: 2

1
Время ByCompiledRegex должно включать компиляцию регулярного выражения в его измерении времени.
Мартин Карни

2
@MartinCarney Я изменил его и оценил компиляцию шаблонов. Очевидно, мой CPU / JIT быстрее, но если я его интерполирую обратно, время компиляции будет 336.
tedder42

2
чтобы было ясно, что 336 (мс) - это то, что происходит, когда компиляция шаблона выполняется 100к раз, как и все остальные строки. С учетом того, что это делается только один раз, его время практически равно нулю.
tedder42

Спасибо за то, что установили запись прямо во время скомпилированного регулярного выражения.
LarsH

Может быть "^[+-]?\\d+$", будет еще лучше.
Адам

34
org.apache.commons.lang.StringUtils.isNumeric 

хотя стандартная библиотека Java действительно пропускает такие вспомогательные функции

Я думаю, что Apache Commons является обязательным условием для каждого Java-программиста

Жаль, что он еще не портирован на Java5


1
Единственная проблема с этим - переполнение: SI все еще дает вам +1 за упоминание commons-lang :)
javamonkey79

2
Другая проблема - отрицательные числа, но я тоже +1, так как, на мой взгляд, этот подход наиболее близок к хорошему решению.
Сандрис

23

Отчасти это зависит от того, что вы подразумеваете под «можно преобразовать в целое число».

Если вы имеете в виду «может быть преобразован в int в Java», то ответ от Jonas - хорошее начало, но не совсем завершает работу. Например, он пройдет 999999999999999999999999999999. Я бы добавил нормальный вызов try / catch из вашего собственного вопроса в конце метода.

Посимвольные проверки будут эффективно отклонять «не целое число» случаев, оставляя «это целое число, но Java не может его обработать», чтобы случаи были обнаружены более медленным маршрутом исключения. Вы можете сделать это немного вручную, но это будет намного сложнее.


17

Только один комментарий о регулярном выражении. Каждый приведенный здесь пример неверен! Если вы хотите использовать регулярные выражения, не забывайте, что компиляция шаблона занимает много времени. Это:

str.matches("^-?\\d+$")

а также это:

Pattern.matches("-?\\d+", input);

вызывает компиляцию шаблона в каждом вызове метода. Чтобы правильно его использовать следуйте:

import java.util.regex.Pattern;

/**
 * @author Rastislav Komara
 */
public class NaturalNumberChecker {
    public static final Pattern PATTERN = Pattern.compile("^\\d+$");

    boolean isNaturalNumber(CharSequence input) {
        return input != null && PATTERN.matcher(input).matches();
    }
}

5
Вы можете немного повысить производительность, создав заранее Matcher и используя метод reset (), чтобы применить его к входным данным.
Алан Мур

13

Есть версия гуавы:

import com.google.common.primitives.Ints;

Integer intValue = Ints.tryParse(stringValue);

Он вернет ноль вместо генерации исключения, если ему не удастся проанализировать строку.


3
Лучший ответ ИМХО. Используйте хорошо протестированные библиотеки вместо того, чтобы свернуть собственное решение. (Также см. Обсуждение здесь .)
Оливье Кайо

12

Я скопировал код из ответа rally25rs и добавил несколько тестов для нецелых данных. Результаты неоспоримо в пользу метода , публикуемую Йонас Klemming. Результаты для метода Exception, который я первоначально опубликовал, довольно хороши, когда у вас есть целочисленные данные, но они хуже, когда у вас их нет, в то время как результаты для решения RegEx (которые, я уверен, многие используют) были постоянно плохими. Смотрите ответ Фелипе для скомпилированного примера регулярных выражений, который намного быстрее.

public void runTests()
{
    String big_int = "1234567890";
    String non_int = "1234XY7890";

    long startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByException(big_int);
    long endTime = System.currentTimeMillis();
    System.out.print("ByException - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByException(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByException - non-integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByRegex(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByRegex - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByRegex(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByRegex - non-integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByJonas(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByJonas - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByJonas(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByJonas - non-integer data: ");
    System.out.println(endTime - startTime);
}

private boolean IsInt_ByException(String str)
{
    try
    {
        Integer.parseInt(str);
        return true;
    }
    catch(NumberFormatException nfe)
    {
        return false;
    }
}

private boolean IsInt_ByRegex(String str)
{
    return str.matches("^-?\\d+$");
}

public boolean IsInt_ByJonas(String str)
{
    if (str == null) {
            return false;
    }
    int length = str.length();
    if (length == 0) {
            return false;
    }
    int i = 0;
    if (str.charAt(0) == '-') {
            if (length == 1) {
                    return false;
            }
            i = 1;
    }
    for (; i < length; i++) {
            char c = str.charAt(i);
            if (c <= '/' || c >= ':') {
                    return false;
            }
    }
    return true;
}

Полученные результаты:

ByException - integer data: 47
ByException - non-integer data: 547

ByRegex - integer data: 390
ByRegex - non-integer data: 313

ByJonas - integer data: 0
ByJonas - non-integer data: 16

6

Это короче, но короче не обязательно лучше (и оно не будет отлавливать целочисленные значения, выходящие за пределы диапазона, как указано в комментарии danatel ):

input.matches("^-?\\d+$");

Лично, поскольку реализация спекулируется в вспомогательном методе, а правильность бьет по длине, я бы просто пошел с чем-то вроде того, что у вас есть (минус перехват базового Exceptionкласса, а не NumberFormatException).


1
И, возможно, \\ d {1,10}, хотя и не идеален, лучше, чем \\ d +, для ловли целых чисел Java
Maglob

6

Вы можете использовать метод совпадений строкового класса. [0-9] представляет все возможные значения, + означает, что длина должна быть не менее одного символа, а * означает, что длина может быть равна нулю или более.

boolean isNumeric = yourString.matches("[0-9]+"); // 1 or more characters long, numbers only
boolean isNumeric = yourString.matches("[0-9]*"); // 0 or more characters long, numbers only

1
Nb этот doest не соответствует "+10" или "-10"), которые обычно включаются как действительные целые числа
Тим Уинтл

4

Как насчет:

return Pattern.matches("-?\\d+", input);

Как насчет целого числа 9999999999999999999999999999999999?
Данатель

Не забудьте проверить наличие отрицательного знака.
Джереми Рутен

Вам не нужно привязывать начало и конец регулярного выражения, чтобы не пропустить "aaa-1999zzz"?
Тим Хоулэнд

2
Тим, когда вы вызываете один из методов match () (каждый из которых имеет String, Pattern и Matcher), регулярное выражение должно соответствовать всему входному значению, делая якоря избыточными. Чтобы найти соответствие, определенное большинством других разновидностей регулярных выражений, вы должны использовать Matcher # find ().
Алан Мур

4

Это вариант ответа Jonas Klemming на Java 8:

public static boolean isInteger(String str) {
    return str != null && str.length() > 0 &&
         IntStream.range(0, str.length()).allMatch(i -> i == 0 && (str.charAt(i) == '-' || str.charAt(i) == '+')
                  || Character.isDigit(str.charAt(i)));
}

Тестовый код:

public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    Arrays.asList("1231231", "-1232312312", "+12313123131", "qwqe123123211", "2", "0000000001111", "", "123-", "++123",
            "123-23", null, "+-123").forEach(s -> {
        System.out.printf("%15s %s%n", s, isInteger(s));
    });
}

Результаты теста кода:

        1231231 true
    -1232312312 true
   +12313123131 true
  qwqe123123211 false
              2 true
  0000000001111 true
                false
           123- false
          ++123 false
         123-23 false
           null false
          +-123 false

3

Вы просто проверяете NumberFormatException : -

 String value="123";
 try  
 {  
    int s=Integer.parseInt(any_int_val);
    // do something when integer values comes 
 }  
 catch(NumberFormatException nfe)  
 {  
          // do something when string values comes 
 }  

3

Если ваш массив String содержит чистые целые числа и строки, код ниже должен работать. Вам нужно только взглянуть на первого персонажа. например, ["4", "44", "abc", "77", "bond"]

if (Character.isDigit(string.charAt(0))) {
    //Do something with int
}

3

Вы также можете использовать класс Scanner и использовать hasNextInt () - и это позволяет вам проверять и другие типы, такие как float и т. Д.


Этот ответ дал мне напоминание, в котором я нуждался. Я полностью забыл, что у Сканера была такая функция. T-Up
Hubro

2

Если вы хотите проверить, представляет ли строка целое число, которое соответствует типу int, я немного изменил ответ jonas, чтобы строки, представляющие целые числа, большие, чем Integer.MAX_VALUE, или меньше, чем Integer.MIN_VALUE, теперь возвращали ложный. Например: «3147483647» вернет false, потому что 3147483647 больше, чем 2147483647, и аналогично «-2147483649» также вернет false, потому что -2147483649 меньше, чем -2147483648.

public static boolean isInt(String s) {
  if(s == null) {
    return false;
  }
  s = s.trim(); //Don't get tricked by whitespaces.
  int len = s.length();
  if(len == 0) {
    return false;
  }
  //The bottom limit of an int is -2147483648 which is 11 chars long.
  //[note that the upper limit (2147483647) is only 10 chars long]
  //Thus any string with more than 11 chars, even if represents a valid integer, 
  //it won't fit in an int.
  if(len > 11) {
    return false;
  }
  char c = s.charAt(0);
  int i = 0;
  //I don't mind the plus sign, so "+13" will return true.
  if(c == '-' || c == '+') {
    //A single "+" or "-" is not a valid integer.
    if(len == 1) {
      return false;
    }
    i = 1;
  }
  //Check if all chars are digits
  for(; i < len; i++) {
    c = s.charAt(i);
    if(c < '0' || c > '9') {
      return false;
    }
  }
  //If we reached this point then we know for sure that the string has at
  //most 11 chars and that they're all digits (the first one might be a '+'
  // or '-' thought).
  //Now we just need to check, for 10 and 11 chars long strings, if the numbers
  //represented by the them don't surpass the limits.
  c = s.charAt(0);
  char l;
  String limit;
  if(len == 10 && c != '-' && c != '+') {
    limit = "2147483647";
    //Now we are going to compare each char of the string with the char in
    //the limit string that has the same index, so if the string is "ABC" and
    //the limit string is "DEF" then we are gonna compare A to D, B to E and so on.
    //c is the current string's char and l is the corresponding limit's char
    //Note that the loop only continues if c == l. Now imagine that our string
    //is "2150000000", 2 == 2 (next), 1 == 1 (next), 5 > 4 as you can see,
    //because 5 > 4 we can guarantee that the string will represent a bigger integer.
    //Similarly, if our string was "2139999999", when we find out that 3 < 4,
    //we can also guarantee that the integer represented will fit in an int.
    for(i = 0; i < len; i++) {
      c = s.charAt(i);
      l = limit.charAt(i);
      if(c > l) {
        return false;
      }
      if(c < l) {
        return true;
      }
    }
  }
  c = s.charAt(0);
  if(len == 11) {
    //If the first char is neither '+' nor '-' then 11 digits represent a 
    //bigger integer than 2147483647 (10 digits).
    if(c != '+' && c != '-') {
      return false;
    }
    limit = (c == '-') ? "-2147483648" : "+2147483647";
    //Here we're applying the same logic that we applied in the previous case
    //ignoring the first char.
    for(i = 1; i < len; i++) {
      c = s.charAt(i);
      l = limit.charAt(i);
      if(c > l) {
        return false;
      }
      if(c < l) {
        return true;
      }
    }
  }
  //The string passed all tests, so it must represent a number that fits
  //in an int...
  return true;
}

1
Можете ли вы отредактировать свой ответ и объяснить, как он улучшает предыдущий ответ, который вы упомянули?
Жиль Гуаиллардет

Спасибо за отличный ответ. Но «123», то есть 123 вместе с пробелом, считается действительным целым числом.
Сайкришна Радарапу

1
@SaikrishnaRadarapu Они используют, trim()так что это явно преднамеренный выбор дизайна.
Гильденстерн


1

Вы, вероятно, должны принять во внимание также вариант использования:

Если большую часть времени вы ожидаете, что числа будут действительными, то перехват исключения приводит только к снижению производительности при попытке преобразовать недопустимые числа. Принимая во внимание , вызывая некоторый isInteger()метод , а затем преобразовать , используя Integer.parseInt()будет всегда причиной над головой производительности для действительных чисел - строки обрабатываются дважды, один раз чек и один раз преобразования.


1

Это модификация кода Джонаса , который проверяет, находится ли строка в пределах диапазона, который будет приведен к целому числу.

public static boolean isInteger(String str) {
    if (str == null) {
        return false;
    }
    int length = str.length();
    int i = 0;

    // set the length and value for highest positive int or lowest negative int
    int maxlength = 10;
    String maxnum = String.valueOf(Integer.MAX_VALUE);
    if (str.charAt(0) == '-') { 
        maxlength = 11;
        i = 1;
        maxnum = String.valueOf(Integer.MIN_VALUE);
    }  

    // verify digit length does not exceed int range
    if (length > maxlength) { 
        return false; 
    }

    // verify that all characters are numbers
    if (maxlength == 11 && length == 1) {
        return false;
    }
    for (int num = i; num < length; num++) {
        char c = str.charAt(num);
        if (c < '0' || c > '9') {
            return false;
        }
    }

    // verify that number value is within int range
    if (length == maxlength) {
        for (; i < length; i++) {
            if (str.charAt(i) < maxnum.charAt(i)) {
                return true;
            }
            else if (str.charAt(i) > maxnum.charAt(i)) {
                return false;
            }
        }
    }
    return true;
}

1
выглядит хорошо, но последний цикл for должен иметь i, сбрасываемый в ноль (или 1, если отрицательное число), потому что цикл, который проверяет, является ли каждая цифра числом, приведет к тому, что я - длина строки, следовательно, последний цикл for никогда не побежит Я бы также использовал Java-константы Integer.MAX_VALUE и Integer.MIN_VALUE вместо магических чисел.
Тим Чародей

@TimtheEnchanter Спасибо за предложения, я их полностью пропустил. В своем редактировании, чтобы включить их, я использовал новую переменную в первом цикле for, чтобы избежать лишнего оператора if.
Уэйн

1

Если вы используете Android API, вы можете использовать:

TextUtils.isDigitsOnly(str);

1

Другой вариант:

private boolean isNumber(String s) {
    boolean isNumber = true;
    for (char c : s.toCharArray()) {
        isNumber = isNumber && Character.isDigit(c);
    }
    return isNumber;
}


0

То, что вы сделали, работает, но вы, вероятно, не всегда должны проверять это. Броски исключений должны быть зарезервированы для «исключительных» ситуаций (возможно, это подходит для вашего случая), и они очень дороги с точки зрения производительности.


Они только дорогостоящие, если их бросают.
Билл Ящерица

0
Number number;
try {
    number = NumberFormat.getInstance().parse("123");
} catch (ParseException e) {
    //not a number - do recovery.
    e.printStackTrace();
}
//use number

0

Это будет работать только для натуральных чисел.

public static boolean isInt(String str) {
    if (str != null && str.length() != 0) {
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) return false;
        }
    }
    return true;        
}

4
Добро пожаловать в stackoverflow. Перед воскрешением старой темы обязательно прочитайте предыдущие ответы и комментарии. Этот метод (и возможные недостатки) фактически уже обсуждались.
Ли

0

Это работает для меня. Просто чтобы определить, является ли String примитивом или числом.

private boolean isPrimitive(String value){
        boolean status=true;
        if(value.length()<1)
            return false;
        for(int i = 0;i<value.length();i++){
            char c=value.charAt(i);
            if(Character.isDigit(c) || c=='.'){

            }else{
                status=false;
                break;
            }
        }
        return status;
    }

0

Чтобы проверить все int-символы, вы можете просто использовать двойной минус.

if (! searchString.matches ("[^ 0-9] + $")) ...

[^ 0-9] + $ проверяет, есть ли какие-либо символы, которые не являются целочисленными, поэтому проверка завершается неудачно, если это правда. Просто НЕ это, и вы получите успех.


Нет. Вы явно не проверяли это. Это возвращает true, только если где-то в строке есть цифра, а не если строка состоит только из цифр. matchesМетод соответствует против всей строки, а не только часть его.
Дауд ибн Карим

Вы не получите двойную отрицательную часть.
Роджер Ф. Гей,

Ну, я НЕ получаю двойной негатив. Это просто не работает. Если у вас есть смесь цифр и букв, это идет в ifблок. Это не должно
Дауд ибн Карим

0

Найти это может быть полезным:

public static boolean isInteger(String self) {
    try {
        Integer.valueOf(self.trim());
        return true;
    } catch (NumberFormatException nfe) {
        return false;
    }
}

0

Я полагаю , что есть нулевой риск нарваться исключение, потому что , как вы можете видеть ниже , Вы всегда безопасно разобрать , intчтобы Stringи не наоборот.

Так:

  1. Вы проверяете, соответствует ли каждый слот символа в вашей строке хотя бы одному из символов {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} .

    if(aString.substring(j, j+1).equals(String.valueOf(i)))
  2. Вы суммируете все времена, которые встречали в слотах вышеперечисленных символов.

    digits++;
  3. И, наконец, вы проверяете, совпадает ли время, в которое вы встречали целые числа как символы, с длиной заданной строки.

    if(digits == aString.length())

И на практике имеем:

    String aString = "1234224245";
    int digits = 0;//count how many digits you encountered
    for(int j=0;j<aString.length();j++){
        for(int i=0;i<=9;i++){
            if(aString.substring(j, j+1).equals(String.valueOf(i)))
                    digits++;
        }
    }
    if(digits == aString.length()){
        System.out.println("It's an integer!!");
        }
    else{
        System.out.println("It's not an integer!!");
    }
    
    String anotherString = "1234f22a4245";
    int anotherDigits = 0;//count how many digits you encountered
    for(int j=0;j<anotherString.length();j++){
        for(int i=0;i<=9;i++){
            if(anotherString.substring(j, j+1).equals(String.valueOf(i)))
                    anotherDigits++;
        }
    }
    if(anotherDigits == anotherString.length()){
        System.out.println("It's an integer!!");
        }
    else{
        System.out.println("It's not an integer!!");
    }

И результаты:

Это целое число!

Это не целое число!

Точно так же вы можете проверить, Stringявляется ли a floatили a, doubleно в этих случаях вам нужно встретиться только с одним. (точка) в строке и, конечно, проверьте, если digits == (aString.length()-1)

Опять же, здесь нет риска столкнуться с исключением при синтаксическом анализе, но если вы планируете выполнить синтаксический анализ известной строки, содержащей число (скажем, int типа данных), вы должны сначала проверить, соответствует ли оно типу данных. В противном случае вы должны разыграть его.

Надеюсь я помог

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.