Как мне конвертировать из int в String? - PullRequest
718 голосов
/ 05 ноября 2010

Я работаю над проектом, в котором все преобразования из int в String выполняются следующим образом:

int i = 5;
String strI = "" + i;

Я не знаком с Java. Это обычная практика или что-то не так, как я полагаю?

Ответы [ 19 ]

931 голосов
/ 05 ноября 2010

Обычные пути будут Integer.toString(i) или String.valueOf(i).

Конкатенация будет работать, но она нетрадиционна и может иметь неприятный запах, так как предполагает, что автор не знает о двух вышеописанных методах (что еще они могут не знать?).

Java имеет специальную поддержку оператора + при использовании со строками (см. документацию ), которая переводит код, который вы разместили в:

StringBuilder sb = new StringBuilder();
sb.append("");
sb.append(i);
String strI = sb.toString();

во время компиляции. Это немного менее эффективно (sb.append() в конечном итоге вызывает Integer.getChars(), что в любом случае Integer.toString() сделал бы), но это работает.

Чтобы ответить на комментарий Гродригеса: ** Нет, компилятор не не оптимизирует пустую строку в этом случае - смотрите:

simon@lucifer:~$ cat TestClass.java
public class TestClass {
  public static void main(String[] args) {
    int i = 5;
    String strI = "" + i;
  }
}
simon@lucifer:~$ javac TestClass.java && javap -c TestClass
Compiled from "TestClass.java"
public class TestClass extends java.lang.Object{
public TestClass();
  Code:
   0:    aload_0
   1:    invokespecial    #1; //Method java/lang/Object."<init>":()V
   4:    return

public static void main(java.lang.String[]);
  Code:
   0:    iconst_5
   1:    istore_1

Инициализировать StringBuilder:

   2:    new    #2; //class java/lang/StringBuilder
   5:    dup
   6:    invokespecial    #3; //Method java/lang/StringBuilder."<init>":()V

Добавить пустую строку:

   9:    ldc    #4; //String
   11:    invokevirtual    #5; //Method java/lang/StringBuilder.append:
(Ljava/lang/String;)Ljava/lang/StringBuilder;

Добавить целое число:

   14:    iload_1
   15:    invokevirtual    #6; //Method java/lang/StringBuilder.append:
(I)Ljava/lang/StringBuilder;

Извлечение окончательной строки:

   18:    invokevirtual    #7; //Method java/lang/StringBuilder.toString:
()Ljava/lang/String;
   21:    astore_2
   22:    return
}

Есть предложение и продолжается работа по изменению этого поведения, нацеленное на JDK 9.

248 голосов
/ 05 ноября 2010

Это приемлемо, но я никогда не писал ничего подобного. Я бы предпочел это:

String strI = Integer.toString(i);
109 голосов
/ 05 ноября 2010

Это не очень хороший способ.

При выполнении преобразования из int в строку следует использовать:

int i = 5;
String strI = String.valueOf(i);
58 голосов
/ 05 ноября 2010

Это не только оптимизация 1 . Мне не нравится

"" + i

потому что это не выражает то, что я действительно хочу сделать 2 .

Я не хочу добавлять целое число к (пустой) строке. Я хочу преобразовать целое число в строку:

Integer.toString(i)

Или, не мой предпочтительный, но все же лучше, чем конкатенация, получить строковое представление объекта (целое число):

String.valueOf(i)

1. Для кода, который вызывается очень часто, как в циклах, оптимизация также является точкой отказа от конкатенации .

2. недопустимо для использования real сцепления, как в System.out.println("Index: " + i); или String id = "ID" + i;

23 голосов
/ 05 ноября 2010

Многие вводные университетские курсы, кажется, преподают этот стиль по двум причинам (по моему опыту):

  • Это не требует понимания классов или методов.Обычно этому учат задолго до того, как слово «класс» когда-либо упоминается, и даже к вызовам методов.Так что использование что-то вроде String.valueOf(…) может сбить студентов с толку.

  • Это иллюстрация «перегрузки оператора» - фактически, это было продано нам как идиоматический перегруженный оператор (не удивительно, поскольку Java не допускает перегрузку пользовательских операторов).

Так что это может быть либо вызвано дидактической необходимостью (хотя я бы сказал, что это простоплохое обучение) или использовать его для иллюстрации принципа, который в Java довольно сложно продемонстрировать.

16 голосов
/ 05 ноября 2010

Выражение

"" + i

приводит к преобразованию строки из i во время выполнения. Общий тип выражения String. i сначала преобразуется в объект Integer (new Integer(i)), затем вызывается String.valueOf(Object obj). Так что это эквивалентно

"" + String.valueOf(new Integer(i));

Очевидно, что это немного менее эффективно, чем просто вызов String.valueOf(new Integer(i)), который даст тот же результат.

Преимущество ""+i в том, что печатать легче / быстрее, и некоторые люди могут подумать, что их легче читать. Это не кодовый запах , поскольку он не указывает на более глубокую проблему.

(Ссылка: JLS 15.8.1 )

14 голосов
/ 05 ноября 2010

Лично я не вижу в этом коде ничего плохого.

Это довольно полезно, когда вы хотите записать значение типа int, и регистратор просто принимает строку. Я бы сказал, что такое преобразование удобно, когда вам нужно вызвать метод, принимающий строку, но у вас есть значение типа int.

Что касается выбора между Integer.toString или String.valueOf, все зависит от вкуса.
... А внутри, кстати, String.valueOf вызывает метод Integer.toString. :)

12 голосов
/ 05 ноября 2010

Другой способ, о котором я знаю, из класса Integer:

Integer.toString(int n);
Integer.toString(int n, int radix);

Конкретный пример (хотя я не думаю, что он вам нужен):

String five = Integer.toString(5); // returns "5"

Это также работает для других примитивных типов, например Double.toString.

Подробнее см. Здесь.

9 голосов
/ 05 ноября 2010

Эту технику преподавали на уроках начального уровня в Java, которые я посещал более десяти лет назад.Однако, я должен отметить, что, IIRC, мы еще не получили методы класса String и Integer.

Техника проста и быстро вводится.Если все, что я делаю, это что-то печатаю, то я буду использовать это (например, System.out.println("" + i);). Однако я думаю, что это не самый лучший способ сделать преобразование, поскольку требуется время, чтобы понять, что происходит, когдаэто используется таким образом. Кроме того, если производительность является проблемой, она кажется медленнее (подробнее ниже, а также в других ответах).

Лично я предпочитаю Integer.toString (), так как очевидно, чтослучается. String.valueOf () будет моим вторым выбором, так как кажется, что он сбивает с толку (посмотрите комментарии после ответа Дарио).

Только для усмешки :) Я написал классы для проверки трех методов: ""+ i, Integer.toString и String.ValueOf.Каждый тест просто конвертировал целые числа от 1 до 10000 в строки.Затем я запускал каждую команду Linux time пять раз.Integer.toString () был немного быстрее, чем String.valueOf () один раз, они связывались три раза, а String.valueOf () был быстрее один раз;однако разница никогда не превышала пары миллисекунд.

Метод "" + i был медленнее, чем оба в каждом тесте, кроме одного, когда он был на 1 миллисекунду быстрее, чем Integer.toString () и 1 миллисекундумедленнее, чем String.valueOf () (очевидно, в том же тесте, где String.valueOf () был быстрее, чем Integer.toString ()).Хотя обычно это было всего на пару миллисекунд медленнее, был один тест, где он был примерно на 50 миллисекунд медленнее. YMMV .

6 голосов
/ 14 августа 2015

Существует несколько способов преобразования в строки:

StringBuilder string = string.append(i).toString();
String string = String.valueOf(i);
String string = Integer.toString(i);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...