Normalmente, uso o seguinte idioma para verificar se uma String pode ser convertida em um número inteiro.
public boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
Sou só eu, ou isso parece um pouco idiota? Qual a melhor maneira?
Veja minha resposta (com benchmarks, com base na resposta anterior de CodingWithSpike ) para ver por que eu inverti minha posição e aceitei a resposta de Jonas Klemming para esse problema. Eu acho que esse código original será usado pela maioria das pessoas porque é mais rápido de implementar e mais sustentável, mas é uma ordem de magnitude mais lenta quando dados não inteiros são fornecidos.
Respostas:
Se você não estiver preocupado com possíveis problemas de estouro, essa função será executada 20 a 30 vezes mais rápido que o uso
Integer.parseInt()
.fonte
Você tem, mas você só deve pegar
NumberFormatException
.fonte
Fez uma referência rápida. Na verdade, as exceções não são tão caras, a menos que você comece a recuperar vários métodos e a JVM tenha que fazer muito trabalho para colocar a pilha de execução no lugar. Ao permanecer no mesmo método, eles não são um bom desempenho.
Resultado:
Concordo que a solução de Jonas K também é a mais robusta. Parece que ele ganha :)
fonte
^
e$
segunda vez desde que emmatches
toda a cadeia tem de corresponder regex, (2)str.matches
cada vez que terá que criar o seu próprioPattern
que é caro. Por razões de desempenho, devemos criar esse padrão apenas uma vez fora deste método e usá-lo dentro. (3) Também podemos criar apenas um objeto Matcher e usá-loreset(CharSequence)
para transmitir dados do usuário e retornar seumatches()
resultado.private final Matcher m = Pattern.compile("-?\\d+").matcher(""); private boolean byRegex(String str) { return m.reset(str).matches(); }
deveria ter melhor desempenho.matches
está adicionando^
e$
implicitamente. Veja o resultado de" 123".matches("\\d+")
e"123".matches("\\d+")
. Você veráfalse
etrue
.false
será retornado porque a cadeia começa com espaço, o que impede que ela seja totalmente correspondida pelo regex.Como existe a possibilidade de as pessoas ainda visitarem aqui e sofrerem um viés contra a Regex após os benchmarks ... Então, darei uma versão atualizada do benchmark, com uma versão compilada do Regex. Ao contrário dos benchmarks anteriores, este mostra que a solução Regex realmente apresenta um desempenho consistente bom.
Copiado de Bill the Lizard e atualizado com a versão compilada:
Resultados:
fonte
336
."^[+-]?\\d+$"
fosse ainda melhor.embora a lib padrão do Java realmente perca essas funções utilitárias
Eu acho que o Apache Commons é um "must have" para todo programador Java
Pena que ainda não foi portado para Java5
fonte
Depende parcialmente do que você quer dizer com "pode ser convertido em um número inteiro".
Se você quer dizer "pode ser convertido em int em Java", a resposta do Jonas é um bom começo, mas não termina o trabalho. Passaria 999999999999999999999999999999, por exemplo. Eu adicionaria a chamada try / catch normal da sua própria pergunta no final do método.
As verificações caractere por caractere rejeitam eficientemente casos "nem um número inteiro", deixando "é um número inteiro, mas Java não pode lidar com" casos a serem capturados pela rota de exceção mais lenta. Você também pode fazer isso manualmente, mas seria muito mais complicado.
fonte
Apenas um comentário sobre o regexp. Todo exemplo fornecido aqui está errado! Se você deseja usar o regexp, não esqueça que a compilação do padrão leva muito tempo. Este:
e também isso:
causa compilação de padrão em todas as chamadas de método. Para usá-lo corretamente, siga:
fonte
Existe a versão goiaba:
Ele retornará nulo em vez de lançar uma exceção se falhar ao analisar a sequência.
fonte
Copiei o código da resposta rally25rs e adicionei alguns testes para dados não inteiros. Os resultados são inegavelmente a favor do método publicado por Jonas Klemming. Os resultados do método Exception que eu publiquei originalmente são muito bons quando você tem dados inteiros, mas são os piores quando não, enquanto os resultados da solução RegEx (que eu aposto que muitas pessoas usam) eram consistentemente ruins. Veja a resposta de Felipe para um exemplo de regex compilado, que é muito mais rápido.
Resultados:
fonte
Isso é mais curto, mas mais curto não é necessariamente melhor (e não captura valores inteiros que estão fora do intervalo, como apontado no comentário da danatel ):
Pessoalmente, como a implementação é desviada em um método auxiliar e a exatidão supera o comprimento, eu iria apenas com algo parecido com o que você tem (menos capturar a
Exception
classe base em vez deNumberFormatException
).fonte
Você pode usar o método de correspondências da classe string. O [0-9] representa todos os valores possíveis, + significa que deve ter pelo menos um caractere e * significa que pode ter zero ou mais caracteres.
fonte
E se:
fonte
Esta é uma variação do Java 8 da resposta de Jonas Klemming:
Código do teste:
Resultados do código de teste:
fonte
Você acabou de verificar NumberFormatException : -
fonte
Se sua matriz String contiver inteiros e seqüências de caracteres puros, o código abaixo deve funcionar. Você só precisa olhar para o primeiro personagem. por exemplo, ["4", "44", "abc", "77", "vínculo"]
fonte
Você também pode usar a classe Scanner e hasNextInt () - e isso permite testar outros tipos também, como carros alegóricos, etc.
fonte
Se você quiser verificar se a string representa um número inteiro que se encaixa em um tipo int, fiz uma pequena modificação na resposta do jonas, para que as strings que representam números inteiros maiores que Integer.MAX_VALUE ou menores que Integer.MIN_VALUE, retornem agora falso. Por exemplo: "3147483647" retornará falso porque 3147483647 é maior que 2147483647 e, da mesma forma, "-2147483649" também retornará falso porque -2147483649 é menor que -2147483648.
fonte
trim()
então essa é claramente uma opção de design intencional.Você pode tentar utilitários apache
Veja o javadoc aqui
fonte
isCreateable(String)
.Você provavelmente também precisará levar em consideração o caso de uso:
Se na maioria das vezes você espera que os números sejam válidos, a captura da exceção causa apenas uma sobrecarga de desempenho ao tentar converter números inválidos. Considerando chamando algum
isInteger()
método e, em seguida, converter usandoInteger.parseInt()
irá sempre causa uma sobrecarga de desempenho para números válidos - as cordas são analisados duas vezes, uma pelo cheque e uma vez pela conversão.fonte
Esta é uma modificação do código de Jonas que verifica se a cadeia está dentro do intervalo para ser convertida em um número inteiro.
fonte
Se você estiver usando a API do Android, poderá usar:
fonte
Outra opção:
fonte
fonte
O que você fez funciona, mas você provavelmente nem sempre deve verificar dessa maneira. O lançamento de exceções deve ser reservado para situações "excepcionais" (talvez isso se encaixe no seu caso) e é muito caro em termos de desempenho.
fonte
fonte
Isso funcionaria apenas para números inteiros positivos.
fonte
Isso funciona para mim. Simplesmente para identificar se uma String é uma primitiva ou um número.
fonte
Para verificar todos os caracteres int, você pode simplesmente usar um duplo negativo.
if (! searchString.matches ("[^ 0-9] + $"))) ...
[^ 0-9] + $ verifica se existem caracteres que não são inteiros; portanto, o teste falha se for verdadeiro. Apenas NÃO e você obtém sucesso no sucesso.
fonte
matches
método corresponde à string inteira, não apenas a uma parte dela.if
bloco. Não deveria.Achar isso útil:
fonte
Acredito que não há risco zero de correr em uma exceção, porque, como você pode ver abaixo, sempre analisa
int
com segurançaString
e não o contrário.Assim:
Você verifica se cada slot de caractere na sua string corresponde a pelo menos um dos caracteres {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} .
Você soma todas as vezes que encontrou nos slots os caracteres acima.
E, finalmente, você verifica se os horários em que você encontrou números inteiros como caracteres são iguais ao comprimento da sequência especificada.
E, na prática, temos:
E os resultados são:
Da mesma forma, você pode validar se a
String
é afloat
ou a,double
mas nesses casos você precisa encontrar apenas um. (ponto) na String e, claro, verifique sedigits == (aString.length()-1)
Espero ter ajudado
fonte