Как мне конвертировать из int в String?

745

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

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

Я не знаком с Java.

Это обычная практика или что-то не так, как я полагаю?

Денис Пальницкий
источник
47
«Глупый, легкий» способ строка = «» + целое число;
Толстяк
1
хороший документ: [ javarevisited.blogspot.de/2011/08/… example
Нараян Еррабачу
2
Я просто имел в виду, это "быстрый, простой" способ сделать это. это немного глупо, но это работает!
Толстяк
1
Мой коллега сделал Integer.valueOf(i).toString(). Должно быть, он любил предметы. В то время как это очень ясно заявляет о его намерении, это немного долго, на мой вкус.
Оле В.В.
5
Вам нужно всего 45 строк кода и реализация 7 интерфейсов для этого.
Ска

Ответы:

958

Нормальные пути были бы 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.

SimonJ
источник
9
что насчет jit-компилятора в jvm? :-) javac не делает никаких изумительных оптимизаций.
Питер Штибраны
5
Кто знает :) javac оптимизирует подобные выражения, когда используются числовые литералы (например, "" + 5становится "5").
SimonJ
5
Да, но зачем тебе это делать, "" + 5а не просто "5"?
Грюнгондола
3
Ницца! +1 за что еще они могут не знать?
Sнаđошƒаӽ
2
"" + integerПодход используется в одном из официальных оракула учебников .
Томаш Ноконь
252

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

String strI = Integer.toString(i);
duffymo
источник
101
Я предпочитаю подход String.valueOf, так как вы можете использовать точно такой же вызов для любого типа.
Джон Скит
1
NumberFormatter будет лучшим подходом
Кастури
Хороший ответ, Кастури. Я бы опубликовал это как нечто большее, чем комментарий.
Даффимо
2
Извините за мое невежество, но разве это не использует нынешнюю культуру? Я иду из .NET фон BTW.
Ε Г И І И О
3
Для целого числа по умолчанию не используется материал, специфичный для культуры (вообще не существует десятичного разделителя или разделителя тысяч). Вот для чего NumberFormatter. Вы можете использовать форматы, как NumberFormat.getInstance(Locale.FRENCH).
Кэт
111

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

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

int i = 5;
String strI = String.valueOf(i);
darioo
источник
7
1. Вы просите пустую строку; 2. Вы просите объединение; 3. поскольку у вас нет строки, вы, наконец, преобразуете свой int в строку. Решение Дариду избежать первых шагов.
Николас
действительно int iполучить коробку к Integerперед тем , как добавляют к String strI?
Кевин Мередит
1
@KevinMeredith, нет, это не так. Вы бы на самом деле вызывали StringBuilder.append(int)(и у вас StringBuilderесть appendметод для всех примитивных типов).
Кат
60

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

"" + i

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

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

Integer.toString(i)

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

String.valueOf(i)

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

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

user85421
источник
3
Люди, которые говорят о производительности в этом контексте, отвлекают. Далеко, далеко, далеко, далеко, далеко, гораздо важнее читаемость .
Брайан Гетц
23

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

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

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

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

Конрад Рудольф
источник
2
я думаю, что наоборот конструкции типа "" + я бы запутал новичков. А также это плохой стиль для остальной части их жизни.
Константин Зюбин
15

Выражение

"" + 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 )

Андреас Долк
источник
3
Ваше «эквивалентное» утверждение не эквивалентно. Даже если вызов String.valueOfнеобходимого бокса i(это не так, поскольку существует перегрузка, которая принимает int), он не будет использовать new Integer(i), он будет использовать Integer.valueOf(i). Но это действительно не делает ничего из этого. Это так new StringBuilder().append("").append(i).toString(), как отмечает ответ SimonJ. StringBuilder имеет свою собственную логику для превращения примитива int iв String.
Марк Питерс
4
Часть о запахе кода верна; Запах кода - неправильный термин здесь. Так что я сниму понижение.
Марк Питерс
Кажется неэффективным делать это с "" + я. Рекомендуется просто использовать Integer.toString или String.valueOf. См. Javadevnotes.com/java-integer-to-string-examples
JavaDev
14

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

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

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

ксю
источник
12

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

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

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

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

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

Смотрите здесь для более подробной информации.

zneak
источник
9

Эту технику преподавали на начальном этапе обучения в классе 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 .

GreenMatt
источник
1
Не забудьте принять во внимание JIT - первые несколько конверсий будут намного медленнее и искажают время. На моем MacBook конкатенация занимает ~ 20 нс дольше, чем два других метода (которые оба требуют ~ 50 нс на конверсию), поэтому различия, которые вы видели в порядке мс, вероятно, вызваны случайной ошибкой (планирование, прерывания и т. Д.).
SimonJ
6

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

StringBuilder string = string.append(i).toString();
String string = String.valueOf(i);
String string = Integer.toString(i);
Шайлей Шимпи
источник
StringBuilder string = string.append (i) .toString (); ... Хм, так это StringBuilder или String? Здесь
какой-то
6

Это зависит от того, как вы хотите использовать свою строку. Это может помочь:

String total =  Integer.toString(123) + Double.toString(456.789);
Ниюхир Жюстин
источник
5

В основном то же самое на SimonJ. Мне действительно не нравится "" + я идиома. Если вы скажете String.valueOf (i), Java преобразует целое число в строку и возвращает результат. Если вы говорите «+ i», Java создает объект StringBuilder, добавляет к нему пустую строку, преобразует целое число в строку, добавляет его в StringBuilder, а затем преобразует StringBuilder в строку. Это много дополнительных шагов. Полагаю, если ты сделаешь это однажды в большой программе, это не страшно. Но если вы делаете это все время, вы заставляете компьютер выполнять кучу дополнительной работы и создаете все эти дополнительные объекты, которые затем необходимо очистить. Я не хочу увлекаться микрооптимизацией, но и не хочу быть бессмысленно расточительным.

сойка
источник
5
String strI = String.valueOf(i);

String string = Integer.toString(i);

Оба способа верны.

Шайлей Шимпи
источник
5

Есть много способов преобразовать целое число в строку:

1)

Integer.toString(10);

2)

 String hundred = String.valueOf(100); // You can pass an int constant
 int ten = 10;
 String ten = String.valueOf(ten)

3)

String thousand = "" + 1000; // String concatenation

4)

String million = String.format("%d", 1000000)
Hoque MD Захидул
источник
1
String.format ("% d", 1000000) ... Это не совсем Int >> Строковое преобразование, это скорее String >> Строковая обработка здесь, несмотря на перегрузку. Поэтому я не рекомендую это. Определенно не для целей просто преобразования.
Франта
5

Есть три способа преобразования в строки

  1. String string = "" + i;
  2. String string = String.valueOf(i);
  3. String string = Integer.toString(i);
Вихан Верма
источник
1
Вы забыли: String.format("%d", i).
Брайан Гетц
3

Использование "" + i - это самый короткий и простой способ преобразовать число в строку. Это не самое эффективное, но самое ясное ИМХО, и это, как правило, более важно. Чем проще код, тем меньше вероятность ошибиться.

Питер Лори
источник
2
Как можно ошибиться при вызове String.valueOf или Integer.toString?
Ева
1
Я столкнулся с парой неидеальных применений String.valueOf (), но я не могу вспомнить их сейчас. Хотя вывод был правильным, он был менее эффективен, чем""+i
Питер Лоури,
2

Лично я думаю, что "+" я выгляжу так, как в оригинальном плакате с вопросом "вонючий". Я использовал много ОО языков помимо Java. Если этот синтаксис задумывался как подходящий, то Java просто интерпретировала бы один i без необходимости "", как требуется для преобразования в строку, и делала бы это, поскольку тип назначения однозначен, а справа указывалось бы только одно значение. , Другое похоже на «обман», чтобы обмануть компилятор, плохое умение, когда рассматриваются разные версии Javac, сделанные другими производителями или с других платформ, если когда-либо нужно будет портировать код. Черт возьми, мне нравятся многие другие OOL просто возьмите Typecast: (String) я. подмигивает

Учитывая мой способ обучения и простоту понимания такой конструкции при быстром чтении чужого кода, я голосую за метод Integer.toString (i). Забывая ns или two в том, как Java реализует вещи в фоновом режиме по сравнению со String.valueOf (i), этот метод мне подходит и точно говорит, что происходит: у меня есть и Integer, и я хочу, чтобы он был преобразован в строку.

Хорошее замечание, сделанное пару раз, возможно, просто использование StringBuilder в начале - хороший ответ для построения строк, смешанных с текстом и целыми числами или другими объектами, поскольку это то, что в любом случае будет использоваться в фоновом режиме, верно?

Только мои два цента брошены в и без того хорошо оплачиваемую кошечку ответов на вопрос Мана ... улыбается

РЕДАКТИРОВАТЬ НА МОЙ СОБСТВЕННЫЙ ОТВЕТ ПОСЛЕ НЕКОТОРЫХ ОТРАЖЕНИЙ:

Хорошо, хорошо, я подумал об этом еще немного, и String.valueOf (i) также совершенно хорош, и он говорит: я хочу строку, которая представляет значение целого числа. LOL, английский намного сложнее разобрать, чем Java! Но я оставляю оставшуюся часть моего ответа / комментария ... Меня всегда учили использовать самый низкий уровень цепочки методов / функций, если это возможно, и все еще поддерживают читабельность, поэтому, если String.valueOf вызывает Integer.toString, тогда зачем использовать весь оранжевый если ты все равно будешь чистить его, хммм?

Чтобы прояснить мой комментарий о StringBuilder, я строю множество строк с комбинациями в основном буквального текста и целых чисел, и они становятся длинными и безобразными с вызовами вышеупомянутых подпрограмм, встроенных между +, так что мне кажется, если они становятся В любом случае, SB возражает, и у метода append есть перегрузки, может быть, будет чище просто продолжать и использовать его ... Так что я полагаю, что сейчас у меня до 5 центов, а? лол...

Дэвид
источник
-1

использование Integer.toString(tmpInt).trim();

Каран Чунара
источник
Здесь действительно нет ситуации, trim()которая бы пригодилась здесь.
Дориан Грэй,
-5

Попробуйте простое приведение типов

char c = (char) i;
Билал хайдер
источник
3
Это не хороший способ конвертировать int в строку. На самом деле, вы не конвертируете int в строку, вы конвертируете int в char. Это будет интерпретировать int как код символа ASCII и даст вам этот символ. Это опасно (отрицательные значения и т. Д.) И в целом просто неправильно.
Nepoxx
Удалите вышеуказанный вопрос, char и String оба отличаются ...!
но это работает (ASCII кодировка "смещение"):char c = (char) (i + 48);
electrobabe