Maneira mais eficiente de converter String para Integer em java

Existem muitas maneiras de converter um String em um object Integer. Qual é o mais eficiente entre os abaixo:

Integer.valueOf() Integer.parseInt() org.apache.commons.beanutils.converters.IntegerConverter 

Meu usecase precisa criar objects Integer do wrapper … significando não int primitivo … e os dados convertidos são usados ​​para somente leitura.

Nem perca tempo pensando nisso. Basta escolher uma que pareça se encheckboxr com o restante do código (as outras conversões usam o método .parse __ () ou .valueOf ()? Use isso para ser consistente).

Tentar decidir o que é “melhor” diminui seu foco de solucionar o problema de negócios ou implementar o recurso.

Não se atole com detalhes triviais. 🙂

Em uma nota à parte, se o seu “caso de uso” estiver especificando tipos de dados do object java para o seu código, sua BA precisará sair do seu domínio. BA precisa definir “o problema de negócios” e como o usuário gostaria de interagir com o aplicativo ao resolver o problema. Os desenvolvedores determinam a melhor forma de criar esse recurso no aplicativo com código – incluindo os tipos / objects de dados apropriados para manipular os dados.

Se a eficiência é sua preocupação, criar um object Integer é muito mais caro do que analisá-lo. Se você tiver que criar um object Integer, eu não me preocuparia muito sobre como ele é analisado.

Nota: O Java 6u14 permite aumentar o tamanho do seu pool Integer com uma opção de linha de comando -Djava.lang.Integer.IntegerCache.high = 1024, por exemplo.

Nota 2: Se você estiver lendo dados brutos, por exemplo, bytes de um arquivo ou rede, a conversão desses bytes em uma String também é relativamente cara. Se você for escrever um analisador customizado, sugiro ignorar a etapa de conversar com uma string e analisar os dados de origem brutos.

Nota 3: Se você estiver criando um Integer para poder colocá-lo em uma coleção, você pode evitar isso usando o GNU Trove (trove4j), que permite armazenar primitivas em collections, permitindo que você elimine a criação Integer também.

Idealmente, para melhor desempenho, você deseja evitar a criação de objects.

Sua melhor aposta é usar Integer.parseInt. Isso retornará um int , mas isso pode ser auto-boxed para um Integer. Isso é um pouco mais rápido que valueOf, já que quando seus números estão entre -128 e 127, ele usa o cache Integer e não cria novos objects. O mais lento é o método Apache.

 private String data = "99"; public void testParseInt() throws Exception { long start = System.currentTimeMillis(); long count = 0; for (int i = 0; i < 100000000; i++) { Integer o = Integer.parseInt(data); count += o.hashCode(); } long diff = System.currentTimeMillis() - start; System.out.println("parseInt completed in " + diff + "ms"); assert 9900000000L == count; } public void testValueOf() throws Exception { long start = System.currentTimeMillis(); long count = 0; for (int i = 0; i < 100000000; i++) { Integer o = Integer.valueOf(data); count += o.hashCode(); } long diff = System.currentTimeMillis() - start; System.out.println("valueOf completed in " + diff + "ms"); assert 9900000000L == count; } public void testIntegerConverter() throws Exception { long start = System.currentTimeMillis(); IntegerConverter c = new IntegerConverter(); long count = 0; for (int i = 0; i < 100000000; i++) { Integer o = (Integer) c.convert(Integer.class, data); count += o.hashCode(); } long diff = System.currentTimeMillis() - start; System.out.println("IntegerConverter completed in " + diff + "ms"); assert 9900000000L == count; } parseInt completed in 5906ms valueOf completed in 7047ms IntegerConverter completed in 7906ms 

Eu sei que isso não está entre as opções acima. IntegerConverter está ok, mas você precisa criar uma instância dele. Dê uma olhada no NumberUtils em Commons Lang:

Commons Lang NumberUtils

isso fornece o método toInt:

 static int toInt(java.lang.String str, int defaultValue) 

que permite especificar um valor padrão no caso de uma falha.

 NumberUtils.toInt("1", 0) = 1 

Essa é a melhor solução que encontrei até agora.

Eu sempre me surpreendo com a rapidez com que muitos aqui descartam alguma investigação sobre problemas de desempenho. Analisar um int para a base 10 é uma tarefa muito comum em muitos programas. Tornar isso mais rápido pode ter um efeito positivo notável em muitos ambientes.

Como parsing e int são realmente uma tarefa trivial, tentei implementar uma abordagem mais direta do que a usada na implementação do JDK que possui base variável. Ele se mostrou mais do que duas vezes mais rápido e deveria se comportar exatamente da mesma forma que Integer.parseInt ().

 public static int intValueOf( String str ) { int ival = 0, idx = 0, end; boolean sign = false; char ch; if( str == null || ( end = str.length() ) == 0 || ( ( ch = str.charAt( 0 ) ) < '0' || ch > '9' ) && ( !( sign = ch == '-' ) || ++idx == end || ( ( ch = str.charAt( idx ) ) < '0' || ch > '9' ) ) ) throw new NumberFormatException( str ); for(;; ival *= 10 ) { ival += '0'- ch; if( ++idx == end ) return sign ? ival : -ival; if( ( ch = str.charAt( idx ) ) < '0' || ch > '9' ) throw new NumberFormatException( str ); } } 

Para obter um object Integer, use o autoboxing ou o explicit

Interger.valueOf( intValueOf( str ) ) .

Se a eficiência é sua preocupação, use int: é muito mais rápido que Integer.

Caso contrário, a class Integer oferece pelo menos algumas maneiras claras e limpas:

 Integer myInteger = new Integer(someString); Integer anotherInteger = Integer.valueOf(someOtherString); 

Aqui está um bom artigo comparando o desempenho de diferentes methods de análise de inteiros

E aqui está o código usado, com verificações de overflow / underflow.

 public static int parseInt( final String s ) { if ( string == null ) throw new NumberFormatException( "Null string" ); // Check for a sign. int num = 0; int sign = -1; final int len = s.length( ); final char ch = s.charAt( 0 ); if ( ch == '-' ) { if ( len == 1 ) throw new NumberFormatException( "Missing digits: " + s ); sign = 1; } else { final int d = ch - '0'; if ( d < 0 || d > 9 ) throw new NumberFormatException( "Malformed: " + s ); num = -d; } // Build the number. final int max = (sign == -1) ? -Integer.MAX_VALUE : Integer.MIN_VALUE; final int multmax = max / 10; int i = 1; while ( i < len ) { int d = s.charAt(i++) - '0'; if ( d < 0 || d > 9 ) throw new NumberFormatException( "Malformed: " + s ); if ( num < multmax ) throw new NumberFormatException( "Over/underflow: " + s ); num *= 10; if ( num < (max+d) ) throw new NumberFormatException( "Over/underflow: " + s ); num -= d; } return sign * num; } 

E implementação ainda mais rápida, sem verificações de overflow / underflow.

 public static int parseInt( final String s ) { // Check for a sign. int num = 0; int sign = -1; final int len = s.length( ); final char ch = s.charAt( 0 ); if ( ch == '-' ) sign = 1; else num = '0' - ch; // Build the number. int i = 1; while ( i < len ) num = num*10 + '0' - s.charAt( i++ ); return sign * num; } 

Eu tentei uma comparação de valueOf, parseInt, Ints.tryParse, NumberUtils.createInteger e NumberUtils.toInt com o programa abaixo. Eu estava no jdk 1.8.0

Como esperado, os methods que não precisaram criar um object Integer foram os mais rápidos. Meus resultados foram:

 valueOf took: 77 parseInt took: 61 Ints.tryParse took: 117 numberUtils.createInteger took: 169 numberUtils.toInt took: 63 

Então o resumo é:

Se você conseguir usar um int, use Integer.parseInt.

Se você absolutamente precisa de um Integer, use Integer.valueOf

Se você precisar da conveniência de não manipular exceções ao analisar ou se não tiver certeza do formato da input (ou seja, uma cadeia que não precisa ser um número), use Ints.tryParse

O código que usei foi:

 public class HelloWorld { public static int limit = 1000000; public static String sint = "9999"; public static void main(String[] args) { long start = System.currentTimeMillis(); for (int i = 0; i < limit; i++) { Integer integer = Integer.valueOf(sint); } long end = System.currentTimeMillis(); System.out.println("valueOf took: " + (end - start)); start = System.currentTimeMillis(); for (int i = 0; i < limit; i++) { int integer = Integer.parseInt(sint); } end = System.currentTimeMillis(); System.out.println("parseInt took: " + (end - start)); start = System.currentTimeMillis(); for (int i = 0; i < limit; i++) { int integer = Ints.tryParse(sint); } end = System.currentTimeMillis(); System.out.println("Ints.tryParse took: " + (end - start)); start = System.currentTimeMillis(); for (int i = 0; i < limit; i++) { Integer integer = NumberUtils.createInteger(sint); } end = System.currentTimeMillis(); System.out.println("numberUtils.createInteger took: " + (end - start)); start = System.currentTimeMillis(); for (int i = 0; i < limit; i++) { int integer = NumberUtils.toInt(sint); } end = System.currentTimeMillis(); System.out.println("numberUtils.toInt took: " + (end - start)); } } 

ParseInt retorna um int, não um java.lang.Integer, então se você usar o método tat você teria que fazer

 new Integer (Integer.parseInt(number)); 

Eu ouvi muitas vezes que chamar Integer.valueOf () em vez de new Integer () é melhor por motivos de memory (isso vem para pmd)

No JDK 1.5, chamar new Integer () causa alocação de memory. Integer.valueOf () é mais amigável à memory.

http://pmd.sourceforge.net/rules/migrating.html

Além disso, Integer.valueOf permite o armazenamento em cache, uma vez que os valores de -127 a 128 têm a garantia de instâncias armazenadas em cache. (desde java 1.5)

Herro – meio novo em Java, perdoe minha ignorância.

Eu estava procurando por uma maneira de analisar uma string mista (letras e números) em um INT (como o javascript faz). Não foi possível encontrar nada nos arquivos JAVADOC, portanto, depois de muita pesquisa, acabei de escrever uma function que faz isso:

 // This function takes a string mixed with numbers and letters and returns an INT with // the first occurrence of a number (INT) in said string, ignoring the rest; // -- Basically, loop checks if char is a digit, if yes, puts digit back into new array, if no, puts a whitespace in its place // this creates an array with only digits; By converting it to a string and then trimming whitespaces, it gets parsed into an INT public static int mixedStringToInt (String str) { boolean flag = true; boolean isNumber = false; final String refNumbers = "0123456789"; int strlen = str.length(); char[] numberArray = new char[strlen]; char[] stringArray = str.toCharArray(); for (int i = 0; i < strlen;i++){ if(refNumbers.indexOf(stringArray[i]) > 0 && flag){ // if current char is a digit isNumber = true; while (flag){ numberArray[i] = stringArray[i]; if(i+1 >= strlen || refNumbers.indexOf(stringArray[i+1]) < 0) flag = false; i++; } } else { // if current char is not a digit numberArray[i] = ' '; } } if (isNumber){ return Integer.valueOf(new String(numberArray).trim()); } else return 0; } 

Isso é útil para alguém além de mim? Eu perdi meu tempo escrevendo isso, já existe um método que faz o que eu queria fazer?

Outra maneira é esse método:

 public class stringtoInteger { private static int stringtoInteger(String x) { String value = ""; for (int i = 0; i < x.length(); i++) { char character = x.charAt(i); if (Character.isDigit(character)) { value = value + character; } } return Integer.parseInt(value); } } 

Espero que ajude!