将String转换为Integer对象的方法有很多种。以下哪项是最有效的:
Integer.valueOf()
Integer.parseInt()
org.apache.commons.beanutils.converters.IntegerConverter
我的usecase需要创建包装器Integer对象...意味着没有原始int ...并且转换后的数据用于只读。
答案 0 :(得分:27)
如果您关心效率,那么创建Integer对象比解析它要昂贵得多。如果你必须创建一个Integer对象,我不会过分担心如何解析它。
注意:Java 6u14允许您使用命令行选项-Djava.lang.Integer.IntegerCache.high = 1024来增加整数池的大小。
注意2:如果您正在阅读原始数据,例如来自文件或网络的字节,这些字节到String的转换也相对昂贵。如果您要编写自定义解析器,我建议绕过转换为字符串并解析原始源数据的步骤。
注意3:如果您正在创建一个Integer以便将它放在一个集合中,您可以通过使用GNU Trove(trove4j)来避免这种情况,它允许您在集合中存储基元,允许您放弃整数创建
理想情况下,为了获得最佳性能,您要避免创建任何对象。
答案 1 :(得分:22)
最好的办法是使用Integer.parseInt。这将返回 int ,但这可以自动装入整数。这比valueOf略快,因为当您的数字介于-128和127之间时,它将使用Integer缓存而不是创建新对象。最慢的是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
答案 2 :(得分:10)
我知道这不是你上面的选择。 IntegerConverter没问题,但您需要创建它的实例。看看Commons Lang中的NumberUtils:
这提供了方法toInt:
static int toInt(java.lang.String str, int defaultValue)
允许您在发生故障时指定默认值。
NumberUtils.toInt("1", 0) = 1
这是我迄今为止找到的最佳解决方案。
答案 3 :(得分:7)
我总是惊讶于很多人在很快就对性能问题进行了一些调查。解析基数为10的int是许多程序中非常常见的任务。加快速度可能会在许多环境中产生明显的积极影响。
由于解析和int实际上是一项相当简单的任务,我尝试实现一种比具有可变基础的JDK实现中使用的方法更直接的方法。事实证明它的速度超过了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 );
}
}
要获取它的Integer对象,请使用autoboxing或explicit
Interger.valueOf( intValueOf( str ) )
。
答案 4 :(得分:6)
甚至不要浪费时间思考它。只需选择一个似乎与其余代码相符的内容(其他转换使用.parse __()或.valueOf()方法吗?使用它来保持一致)。
尝试确定哪个是“最佳”会减少您解决业务问题或实施该功能的重点。
不要因为琐碎的细节而陷入困境。 : - )
另外,如果您的“用例”是为您的代码指定java对象数据类型 - 您的BA需要退出域。 BA需要定义“业务问题”,以及用户在解决问题时如何与应用程序进行交互。 开发人员确定如何最好地使用代码将该功能构建到应用程序中 - 包括处理数据的正确数据类型/对象。
答案 5 :(得分:5)
如果您关注效率,请使用int:它比Integer快多。
否则,Integer类至少为您提供了一些清晰,干净的方法:
Integer myInteger = new Integer(someString);
Integer anotherInteger = Integer.valueOf(someOtherString);
答案 6 :(得分:5)
Here's a good article comparing the performance of different methods of parsing integers
这里是使用的代码,带有溢出/下溢检查。
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;
}
更快的实施,没有溢出/下溢检查。
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;
}
答案 7 :(得分:3)
我尝试使用下面的程序比较valueOf,parseInt,Ints.tryParse,NumberUtils.createInteger和NumberUtils.toInt。我在jdk 1.8.0
正如所料,不需要创建Integer对象的方法是最快的。我的结果是:
valueOf took: 77
parseInt took: 61
Ints.tryParse took: 117
numberUtils.createInteger took: 169
numberUtils.toInt took: 63
所以摘要是:
如果可以使用int,请使用Integer.parseInt。
如果您绝对需要Integer,请使用Integer.valueOf
如果您在解析时需要不处理异常的便利,或者您不确定输入的格式(即它不需要是数字的字符串),请使用Ints.tryParse
我使用的代码是:
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));
}
}
答案 8 :(得分:0)
ParseInt返回一个int,而不是java.lang.Integer,所以如果你使用tat方法就必须这样做
new Integer (Integer.parseInt(number));
我曾多次听说调用Integer.valueOf()而不是新的Integer()更好地用于内存原因(这是为了pmd)
在JDK 1.5中,调用new Integer() 导致内存分配。 Integer.valueOf()是更多的内存 友好。
http://pmd.sourceforge.net/rules/migrating.html
除此之外,Integer.valueOf允许缓存,因为保证值-127到128具有缓存实例。 (自java 1.5起)
答案 9 :(得分:0)
Herro - 有点新的Java,请原谅我的无知。
我正在寻找一种方法来将混合字符串(字母和数字)解析为INT(有点像javascript)。无法在JAVADOC文件中找到任何内容,因此经过多次搜索后我才编写了一个函数来执行它:
// 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;
}
这对我以外的人有用吗?我是不是浪费时间写这篇文章,因为已经有一种方法可以做我想做的事情?
答案 10 :(得分:0)
另一种方法是这种方法:
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);
}
}
希望它有所帮助!