Як перетворити з int в String?


745

Я працюю над проектом, у якому всі перетворення від intдо Stringцього робляться так:

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

Я не знайомий з Java.

Це звичайна практика чи щось не так, як я гадаю?


47
Шлях "дурний, простий" - це string = "" + ціле число;
Fattie

1
приємний документ: [ javarevisited.blogspot.de/2011/08/… приклад
Narayan Yerrabachu

2
Я щойно мав на увазі, це "швидкий, простий" спосіб зробити це. це трохи нерозумно, але це працює!
Fattie

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()одно було б зробити), але це працює.

Щоб відповісти на коментар Grodriguez: ** Ні, компілятор не оптимізує порожній рядок у цьому випадку - дивіться:

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.


9
як щодо компілятора jit в jvm? :-) javac не робить будь-яких фантазійних оптимізацій.
Петро Штібрані

5
Хто знає :) javac оптимізує подібні вирази при використанні числових літералів (наприклад, "" + 5стає "5").
SimonJ

5
Так, але чому б ти робив "" + 5замість просто "5"?
Грунгондола

3
Приємно! +1, за що ще вони можуть не знати?
Snađошƒаӽ


252

Це прийнятно, але я ніколи нічого подібного не писав. Я вважаю за краще це:

String strI = Integer.toString(i);

101
Я віддаю перевагу підходу String.valueOf, оскільки ви можете використовувати такий самий виклик для будь-якого типу.
Джон Скіт

1
NumberFormatter був би кращим підходом
Кастурі

Гарна відповідь, Кастурі. Я б опублікував це як щось більше, ніж коментар.
duffymo

2
Вибачте за моє невігластво, але хіба це не використовує сучасну культуру? Я надходжу з .NET фон BTW.
Ε Г І І І О

3
Для цілого числа за замовчуванням не використовується специфічна для культури інформація (десяткового або тисячного роздільника взагалі немає). Ось для чого NumberFormatter. Можна використовувати такі формати NumberFormat.getInstance(Locale.FRENCH).
Кет

111

Це не гарний спосіб.

При здійсненні перетворення з int в рядок слід використовувати це:

int i = 5;
String strI = String.valueOf(i);

7
1. Ви запитуєте порожню рядок; 2. Ви просите приєднання; 3. оскільки у вас немає рядка, ви, нарешті, перетворите ваш int в рядок. Розв’язок daridoo уникає перших кроків.
Ніколя

дійсно 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;


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
Частина про кодовий запах є правильною; запах коду тут неправильний термін. Тож я зніму спуску.
Марк Петерс

Здається, це неефективно робити з "" + i. Рекомендується просто простий Integer.toString або String.valueOf. Дивіться javadevnotes.com/java-integer-to-string-examples
JavaDev

14

Особисто я не бачу нічого поганого в цьому коді.

Це досить корисно, коли ви хочете записати значення int, і реєстратор просто приймає рядок. Я б сказав, що таке перетворення зручно, коли вам потрібно викликати метод, що приймає String, але у вас є значення 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.

Дивіться тут для більш детальної інформації.


9

Цю техніку викладали у бакалаврському курсі впровадження до Java класу, який я взяв понад десять років тому. Однак, зауважу, IIRC, ми ще не знайшли методів класу String і Integer.

Техніка проста і швидка на наборі. Якщо все, що я роблю, це щось надрукувати, я використаю це (наприклад System.out.println("" + i);. Також, якщо продуктивність викликає занепокоєння, вона здається повільнішою (детальніше нижче, як і в інших відповідях).

Особисто я віддаю перевагу Integer.toString (), оскільки очевидно, що відбувається. String.valueOf () був би моїм другим вибором, оскільки він здається заплутаним (засвідчуйте коментарі після відповіді darioo).

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

Техніка "" + i була повільнішою, ніж обидві на кожному тесті, крім одного, коли вона була на 1 мілісекунд швидша, ніж Integer.toString (), і на 1 мілісекунд повільніше, ніж String.valueOf () (очевидно, на тому ж тесті, де String.valueOf () був швидшим, ніж Integer.toString ()). Хоча це було зазвичай на пару мілісекунд повільніше, був один тест, де він був на 50 мілісекунд повільніше. YMMV .


1
Не забудьте взяти до уваги JIT - перші кілька конверсій будуть набагато повільнішими і спотворюватимуть терміни. У моєму MacBook конкатенація займає ~ 20ns довше, ніж у двох інших методів (які обидва беруть ~ 50ns за конверсію), тому розбіжності, які ви бачили в порядку ms, ймовірно, пов'язані з випадковою помилкою (планування, переривання тощо).
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. Це може допомогти:

String total =  Integer.toString(123) + Double.toString(456.789);

5

Переважно дітто на SimonJ. Мені дуже не подобається ідіома "" + i. Якщо ви скажете String.valueOf (i), Java перетворює ціле число в рядок і повертає результат. Якщо ви говорите "" + i, Java створює об'єкт StringBuilder, додає до нього порожню рядок, перетворює ціле число в рядок, додає це до StringBuilder, а потім перетворює StringBuilder в String. Це багато зайвих кроків. Я гадаю, що якщо ти зробиш це один раз у великій програмі, то нічого не складеш. Але якщо ви робите це постійно, ви змушуєте комп’ютер робити купу зайвих робіт і створювати всі ці зайві об’єкти, які потім доведеться очистити. Я не хочу бути фанатичним щодо мікрооптимізації, але я також не хочу бути безглуздо марнотратним.



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)

1
String.format ("% d", 1000000) ... Це насправді не Int >> Перетворення рядків, це швидше String >> Обробка рядків тут, незважаючи на перевантаженість. Тому я цього не рекомендую. Однозначно не для цілей перетворення.
Франта


3

Використання "" + i - це найкоротший і найпростіший спосіб перетворення числа в рядок. Це не найефективніше, але це найбільш чіткий ІМХО, і це, як правило, важливіше. Чим простіший код, тим менше ймовірність помилитися.


2
Як можна помилитися, викликавши String.valueOf або Integer.toString?
Єва

1
Я натрапив на кілька неідеальних способів використання String.valueOf (), але зараз не можу їх запам'ятати. Хоча результат був правильним, він був менш ефективним, ніж""+i
Пітер Лорі

2

Особисто я вважаю, що "" + я справді виглядає так, як оригінальний плакат запитання стверджує "смердючий". Я використовував багато мов OO, крім Java. Якщо цей синтаксис мав бути відповідним, тоді Java просто інтерпретуватиме "i" одне, не потребуючи перетворення "" в потрібний рядок і робити це, оскільки тип призначення однозначний, і праворуч буде надано лише одне значення . Інше здається "хитрощі" обдурити компілятор, погано моджо, коли різні версії Javac, виготовлені іншими виробниками або з інших платформ, розглядаються, якщо код коли-небудь потрібно переносити. візьміть Typecast: (String) i. підморгує

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

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

Тільки мої два центи, кинуті у вже добре оплачену кошенята відповідей на питання Мана ... посміхається

РЕДАКТУЙТЕ ДЛЯ МОЯ ВІДПОВІДА ПІСЛЯ ДЕЯКОЇ ВІДОМОСТІ

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

Щоб уточнити свій коментар про StringBuilder, я будую багато рядків із комбінаціями здебільшого буквального тексту та int's, і вони закінчуються довгими та некрасивими з дзвінками до вищезазначених процедур, закладених між +, так що мені здається, якщо вони стануть Будь-які об’єкти SB, і метод додавання має перевантаження, можливо, чистіше буде просто продовжувати та використовувати його ... Тож, напевно, я зараз на цьому 5 центів, так? Лол...



-5

Спробуйте просту клавіатуру

char c = (char) i;

3
Це не гарний спосіб перетворення int у рядок. Насправді ви не перетворюєте int в рядок, ви перетворюєте int в char. Це буде інтерпретувати int як код символу ASCII і дасть вам цю діаграму. Це небезпечно (негативні значення тощо) і взагалі просто неправильно.
Nepoxx

Очистіть вищезазначене запитання, char та String - це різні ...!

але це працює (діапазон ASCII "офсет"):char c = (char) (i + 48);
electrobabe
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.