在java中将字符串转换为整数的最有效方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1030479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:27:56  来源:igfitidea点击:

Most efficient way of converting String to Integer in java

javaoptimizationperformance

提问by Aravind Yarram

There are many ways of converting a String to an Integer object. Which is the most efficient among the below:

有多种方法可以将 String 转换为 Integer 对象。以下哪个是最有效的:

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

My usecase needs to create wrapper Integer objects...meaning no primitive int...and the converted data is used for read-only.

我的用例需要创建包装 Integer 对象......意味着没有原始 int......并且转换后的数据用于只读。

采纳答案by Ron Savage

Don't even waste time thinking about it. Just pick one that seems to fit with the rest of the code (do other conversions use the .parse__() or .valueOf() method? use that to be consistent).

甚至不要浪费时间思考它。只需选择一个似乎适合其余代码的代码(其他转换是否使用 .parse__() 或 .valueOf() 方法?使用它来保持一致)。

Trying to decide which is "best" detracts your focus from solving the business problem or implementing the feature.

试图决定哪个是“最好的”会分散您对解决业务问题或实现功能的注意力。

Don't bog yourself down with trivial details. :-)

不要因为琐碎的细节而陷入困境。:-)

On a side note, if your "use case" is specifying java object data types for your code - your BA needs to step back out of your domain. BA's need to define "the business problem", and how the user would like to interact with the application when addressing the problem. Developers determine how best to build that feature into the application with code - including the proper data types / objects to handle the data.

附带说明一下,如果您的“用例”正在为您的代码指定 java 对象数据类型 - 您的 BA 需要退出您的域。BA 需要定义“业务问题”,以及用户在解决问题时希望如何与应用程序交互。开发人员确定如何最好地使用代码将该功能构建到应用程序中 - 包括处理数据的正确数据类型/对象。

回答by Jon

I know this isn't amongst your options above. IntegerConverter is ok, but you need to create an instance of it. Take a look at NumberUtils in Commons Lang:

我知道这不在你上面​​的选择中。IntegerConverter 没问题,但你需要创建它的一个实例。看看 Commons Lang 中的 NumberUtils:

Commons Lang NumberUtils

Commons Lang NumberUtils

this provides the method toInt:

这提供了方法 toInt:

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

which allows you to specify a default value in the case of a failure.

它允许您在失败的情况下指定默认值。

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

That's the best solution I've found so far.

这是我目前找到的最好的解决方案。

回答by Tom

ParseInt returns an int, not a java.lang.Integer, so if you use tat method you would have to do

ParseInt 返回一个 int,而不是一个 java.lang.Integer,所以如果你使用 tat 方法,你将不得不这样做

new Integer (Integer.parseInt(number));

I′ve heard many times that calling Integer.valueOf() instead of new Integer() is better for memory reasons (this coming for pmd)

我多次听说调用 Integer.valueOf() 而不是 new Integer() 出于内存原因更好(这适用于 pmd)

In JDK 1.5, calling new Integer() causes memory allocation. Integer.valueOf() is more memory friendly.

在 JDK 1.5 中,调用 new Integer() 会导致内存分配。Integer.valueOf() 对内存更友好。

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

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

In addition to that, Integer.valueOf allows caching, since values -127 to 128 are guaranteed to have cached instances. (since java 1.5)

除此之外,Integer.valueOf 允许缓存,因为值 -127 到 128 保证有缓存实例。(从 Java 1.5 开始)

回答by Jim Ferrans

If efficiency is your concern, use int: it is muchfaster than Integer.

如果效率是您的关心,使用int:它是比整数快。

Otherwise, class Integer offers you at least a couple clear, clean ways:

否则,Integer 类至少为您提供了几种清晰、干净的方法:

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

回答by brianegge

Your best bet is to use Integer.parseInt. This will return an int, but this can be auto-boxed to an Integer. This is slightly faster than valueOf, as when your numbers are between -128 and 127 it will use the Integer cache and not create new objects. The slowest is the Apache method.

最好的办法是使用 Integer.parseInt。这将返回一个int,但这可以自动装箱为一个整数。这比 valueOf 稍快,因为当您的数字介于 -128 和 127 之间时,它将使用整数缓存而不是创建新对象。最慢的是 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

回答by Peter Lawrey

If efficiency is your concern, then creating an Integer object is much more expensive than parsing it. If you have to create an Integer object, I wouldn't worry too much about how it is parsed.

如果您关心效率,那么创建一个 Integer 对象比解析它要昂贵得多。如果您必须创建一个 Integer 对象,我不会太担心它是如何解析的。

Note: Java 6u14 allows you to increase the size of your Integer pool with a command line option -Djava.lang.Integer.IntegerCache.high=1024 for example.

注意:例如,Java 6u14 允许您使用命令行选项 -Djava.lang.Integer.IntegerCache.high=1024 来增加整数池的大小。

Note 2: If you are reading raw data e.g. bytes from a file or network, the conversion of these bytes to a String is relatively expensive as well. If you are going to write a custom parser I suggest bypassing the step of conversing to a string and parse the raw source data.

注意 2:如果您正在读取原始数据,例如从文件或网络中读取字节,将这些字节转换为字符串的成本也相对较高。如果您打算编写自定义解析器,我建议绕过转换为字符串并解析原始源数据的步骤。

Note 3: If you are creating an Integer so you can put it in a collection, you can avoid this by using GNU Trove (trove4j) which allows you to store primitives in collections, allowing you to drop the Integer creation as well.

注意 3:如果您正在创建一个整数以便将其放入集合中,则可以通过使用 GNU Trove (trove4j) 来避免这种情况,它允许您将原语存储在集合中,从而也允许您删除 Integer 创建。

Ideally, for best performance you want to avoid creating any objects at all.

理想情况下,为了获得最佳性能,您希望完全避免创建任何对象。

回答by x4u

I'm always amazed how quickly many here dismiss some investigation into performance problems. Parsing a int for base 10 is a very common task in many programs. Making this faster could have a noticable positive effect in many environments.

我总是惊讶于这里的许多人对性能问题的调查是多么迅速。解析基数为 10 的 int 是许多程序中非常常见的任务。加快速度可能会在许多环境中产生显着的积极影响。

As parsing and int is actually a rather trivial task, I tried to implement a more direct approach than the one used in the JDK implementation that has variable base. It turned out to be more than twice as fast and should otherwise behave exactly the same as Integer.parseInt().

由于解析和 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 );
    }
}

To get an Integer object of it, either use autoboxing or explicit

要获取它的 Integer 对象,请使用自动装箱或显式

Interger.valueOf( intValueOf( str ) ).

Interger.valueOf( intValueOf( str ) ).

回答by Matt

Herro - kinda new to Java so forgive my ignorance.

Herro - 对 Java 有点陌生,所以请原谅我的无知。

I was searching for a a way to parse a mixed string (letters & numbers) into an INT (kinda like javascript does). Couldn't find anything in the JAVADOC files so after much searching i just wrote a function that does it:

我正在寻找一种将混合字符串(字母和数字)解析为 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;
}





Is this useful for anyone besides me? Did i waste my time writing this as there is already a method that does what i wanted to do?





这对我以外的任何人有用吗?我是否在浪费时间写这篇文章,因为已经有一种方法可以完成我想做的事情?

回答by malitha619

Another way is this method:

另一种方法是这种方法:

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);
    }
}  

Hope it helps!

希望能帮助到你!

回答by Somaiah Kumbera

I tried a comparison of valueOf, parseInt, Ints.tryParse, NumberUtils.createInteger and NumberUtils.toInt with the program below. I was on jdk 1.8.0

我尝试将 valueOf、parseInt、Ints.tryParse、NumberUtils.createInteger 和 NumberUtils.toInt 与下面的程序进行比较。我在 jdk 1.8.0

As expected, the methods that did not need to create an Integer object were the fastest. My results were:

正如预期的那样,不需要创建 Integer 对象的方法是最快的。我的结果是:

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

So the summary is:

所以总结如下:

If you can get by using an int, use Integer.parseInt.

如果您可以通过使用 int 获得,请使用 Integer.parseInt。

If you absolutely need an Integer, use Integer.valueOf

如果您绝对需要一个整数,请使用 Integer.valueOf

If you need the convenience of not handling exceptions when you parse, or if you are unsure of the format of the input (i.e its a string that need not be a number) use Ints.tryParse

如果您在解析时需要不处理异常的便利,或者您不确定输入的格式(即它是一个不需要是数字的字符串),请使用 Ints.tryParse

The code I used was:

我使用的代码是:

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));

}
}