Подтвердить что ты не робот

Наиболее эффективный способ преобразования String в Integer в java

Существует много способов преобразования String в объект Integer. Что наиболее эффективно среди ниже:

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

My usecase необходимо создать обертывающие объекты Integer... не означает, что примитивный int... и преобразованные данные используются только для чтения.

4b9b3361

Ответ 1

Не тратьте время на размышления об этом. Просто выберите тот, который, похоже, соответствует остальной части кода (в других преобразованиях используется метод .parse __() или .valueOf(), который должен быть последовательным).

Попытка решить, какой из них "лучше всего", отвлекает ваше внимание от решения бизнес-задачи или реализации этой функции.

Не бойтесь себя тривиальными деталями.: -)

На стороне примечания, если ваш "пример использования" указывает типы данных объектов Java для вашего кода, вашему BA необходимо отступить от вашего домена. BA необходимо определить "бизнес-проблему" и как пользователь хочет взаимодействовать с приложением при решении проблемы. Разработчики определяют, как лучше всего создавать эту функцию в приложении с кодом, включая правильные типы данных/объекты для обработки данных.

Ответ 2

Если ваша задача связана с эффективностью, то создание объекта Integer намного дороже, чем синтаксический анализ. Если вам нужно создать объект Integer, я бы не стал слишком беспокоиться о том, как он разбирается.

Примечание. Java 6u14 позволяет вам увеличить размер пула Integer с параметром командной строки -Djava.lang.Integer.IntegerCache.high = 1024, например.

Примечание 2: Если вы читаете необработанные данные, например. байтов из файла или сети, преобразование этих байтов в строку также относительно дорого. Если вы собираетесь написать собственный парсер, я предлагаю обходить шаг беседы с строкой и анализировать исходные данные.

Примечание 3: Если вы создаете Integer, чтобы вы могли поместить его в коллекцию, вы можете избежать этого, используя GNU Trove (trove4j), который позволяет хранить примитивы в коллекциях, что позволяет также отбросить создание целых чисел.

В идеале, для лучшей производительности вы хотите вообще не создавать какие-либо объекты.

Ответ 3

Лучше всего использовать Integer.parseInt. Это вернет int, но это может быть автоматически помечено в Integer. Это немного быстрее, чем 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

Ответ 4

Я знаю, что это не одно из ваших вариантов выше. IntegerConverter в порядке, но вам нужно создать экземпляр. Взгляните на NumberUtils в Commons Lang:

Commons Lang NumberUtils

это обеспечивает метод toInt:

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

который позволяет указать значение по умолчанию в случае сбоя.

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

Это лучшее решение, которое я нашел до сих пор.

Ответ 5

Если эффективность ваша, используйте int: она намного быстрее, чем Integer.

В противном случае класс Integer предлагает вам хотя бы пару четких и чистых способов:

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

Ответ 6

Я всегда удивляюсь, как быстро многие из них отклоняют некоторые исследования проблем производительности. Разбор int для базы 10 является очень распространенной задачей во многих программах. Быстрое выполнение этого показателя может иметь заметный положительный эффект во многих средах.

Поскольку синтаксический анализ и 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, либо явно

Interger.valueOf( intValueOf( str ) ).

Ответ 7

Вот хорошая статья, сравнивающая производительность различных методов синтаксического анализа целых чисел

И здесь используется код, с проверкой переполнения/недополнения.

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

Ответ 8

Я попытался сравнить значения 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));

}
}

Ответ 9

ParseInt возвращает int, а не java.lang.Integer, поэтому, если вы используете метод tat, вам нужно будет

new Integer (Integer.parseInt(number));

Я слышал много раз, что вызов Integer.valueOf() вместо нового Integer() лучше по соображениям памяти (это происходит для pmd)

В JDK 1.5 вызов нового Integer() вызывает выделение памяти. Integer.valueOf() - больше памяти удобно.

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

В дополнение к этому, Integer.valueOf позволяет кэшировать, так как гарантированно, что значения -127 до 128 имеют кэшированные экземпляры. (с java 1.5)

Ответ 10

Герро - своего рода новый для 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;
}





Это полезно для всех, кроме меня? Разве я трачу свое время на это, потому что уже существует метод, который делает то, что я хотел сделать?

Ответ 11

Другим способом является этот метод:

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

Надеюсь, что это поможет!