Jak przekonwertować z int na String?

745

Pracuję nad projektem, w którym wszystkie konwersje od intdo Stringsą wykonywane w następujący sposób:

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

Nie znam Java.

Czy to zwykła praktyka, czy coś jest nie tak, jak sądzę?

Denis Palnicki
źródło
47
„Głupie, proste” sposobem jest ciąg = „” + liczba całkowita;
Fattie
1
fajny dokument: [ javarevisited.blogspot.de/2011/08/… przykład
Narayan Yerrabachu
2
Chciałem tylko powiedzieć, że jest to „szybki, prosty” sposób na zrobienie tego. to trochę głupie, ale działa!
Fattie
1
Mój kolega to zrobił Integer.valueOf(i).toString(). Musiał lubić przedmioty. Chociaż bardzo wyraźnie określa to jego zamiar, na mój gust jest to trochę za długo.
Ole VV
5
Potrzebujesz tylko 45 linii kodu i implementacji 7 interfejsów, aby to zrobić.
Ska

Odpowiedzi:

958

Normalne sposoby byłyby Integer.toString(i)lub String.valueOf(i).

Konkatenacja będzie działać, ale jest niekonwencjonalna i może być nieprzyjemnym zapachem, ponieważ sugeruje, że autor nie wie o dwóch powyższych metodach (co jeszcze może nie wiedzieć?).

Java ma specjalne wsparcie dla operatora +, gdy jest używany z ciągami (patrz dokumentacja ), co tłumaczy opublikowany kod:

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

w czasie kompilacji. Jest nieco mniej wydajny ( sb.append()kończy się sprawdzanie Integer.getChars(), co i tak Integer.toString()by zrobił), ale działa.

Aby odpowiedzieć na komentarz Grodrigueza: ** Nie, kompilator nie optymalizuje w tym przypadku pustego ciągu - spójrz:

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

Zainicjuj StringBuilder:

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

Dołącz pusty ciąg:

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

Dołącz liczbę całkowitą:

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

Wyodrębnij ostatni ciąg:

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

Istnieje propozycja i trwają prace nad zmianą tego zachowania, ukierunkowane na JDK 9.

SimonJ
źródło
9
co z kompilatorem jit w jvm? :-) javac nie wykonuje żadnych fantazyjnych optymalizacji.
Peter Štibraný
5
Kto wie :) javac optymalizuje tego rodzaju wyrażenia, gdy używane są literały liczbowe (np. "" + 5Staje się "5").
SimonJ
5
Tak, ale dlaczego miałbyś zrobić "" + 5zamiast tego "5"?
Grungondola
3
Miły! +1 za to, czego jeszcze mogliby nie wiedzieć?
Sнаđошƒаӽ
2
"" + integerPodejście jest stosowane w jednym z urzędowych tutoriali oracle .
Tomasz Nocoń
252

Jest do przyjęcia, ale nigdy czegoś takiego nie napisałem. Wolałbym to:

String strI = Integer.toString(i);
duffymo
źródło
101
Wolę podejście String.valueOf, ponieważ można użyć dokładnie tego samego wywołania dla dowolnego typu.
Jon Skeet,
1
NumberFormatter byłby lepszym podejściem
Kasturi
Dobra odpowiedź, Kasturi. Zamieściłbym to jako coś więcej niż komentarz.
duffymo,
2
Przepraszam za moją ignorancję, ale czy nie wykorzystałoby to obecnej kultury? Idę z BTW w tle .NET.
Ε Г И І И О
3
W przypadku liczby całkowitej domyślnie nie są używane elementy specyficzne dla kultury (nie ma w ogóle separatora dziesiętnego ani tysięcy). Po to NumberFormatterjest. Możesz używać formatów takich jak NumberFormat.getInstance(Locale.FRENCH).
Kat
111

To nie jest dobry sposób.

Podczas konwersji z int na string należy użyć:

int i = 5;
String strI = String.valueOf(i);
Darioo
źródło
7
1. Pytasz o pusty ciąg; 2. Prosisz o konkatenację; 3. ponieważ nie masz łańcucha, w końcu przekształcisz int w łańcuch. Rozwiązanie daridoo pozwala uniknąć pierwszych kroków.
Nicolas,
ma int idostać zapakowane do Integerprzed uzyskiwanie dodany do String strI?
Kevin Meredith
1
@KevinMeredith, nie, nie ma. Będziesz faktycznie dzwonił StringBuilder.append(int)(i StringBuilderma appendmetodę dla wszystkich typów pierwotnych).
Kat
60

To nie tylko optymalizacja 1 . Nie lubie

"" + i

ponieważ nie wyraża tego, co naprawdę chcę zrobić 2 .

Nie chcę dodawać liczby całkowitej do (pustego) ciągu. Chcę przekonwertować liczbę całkowitą na ciąg:

Integer.toString(i)

Lub, nie mój preferowany, ale wciąż lepszy niż konkatenacja, uzyskaj reprezentację ciągu obiektu (liczba całkowita):

String.valueOf(i)

1. W przypadku kodu, który jest wywoływany bardzo często, np. W pętlach, optymalizacja jest również wskazana, aby nie używać konkatenacji .

2. nie dotyczy to rzeczywistej konkatenacji jak w System.out.println("Index: " + i); lub String id = "ID" + i;

użytkownik85421
źródło
3
Ludzie, którzy mówią o wydajności w tym kontekście, rozpraszają uwagę. Daleko, daleko, daleko, daleko, daleko, znacznie ważniejsza jest czytelność .
Brian Goetz
23

Wiele wprowadzających kursów uniwersyteckich wydaje się uczyć tego stylu z dwóch powodów (z mojego doświadczenia):

  • Nie wymaga zrozumienia klas ani metod. Zazwyczaj uczy się tego na długo przed tym, zanim słowo „klasa” zostanie wspomniane - a nawet wywołania metod. Używanie czegoś takiego String.valueOf(…)mogłoby dezorientować studentów.

  • Jest to ilustracja „operator przeciążenie” - w rzeczywistości, to został sprzedany do nas jako do idiomatycznym operator przeciążony (Nic dziwnego tutaj, ponieważ Java nie pozwala na niestandardowe operatora przeciążenia).

Może więc zrodzić się z konieczności dydaktycznej (chociaż twierdzę, że jest to po prostu złe nauczanie) lub może być wykorzystany do zilustrowania zasady, która poza tym byłaby trudna do wykazania w Javie.

Konrad Rudolph
źródło
2
myślę, że wręcz przeciwnie, konstrukcje takie jak „” + wprowadzałyby w błąd początkujących. A także to zły styl na resztę życia.
Konstantin Zyubin,
15

Ekspresja

"" + i

prowadzi do konwersji łańcucha z iprzy starcie. Ogólny typ wyrażenia to String. ijest najpierw konwertowany na Integerobiekt ( new Integer(i)), a następnie String.valueOf(Object obj)wywoływany. Jest to więc równoważne z

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

Oczywiście jest to nieco mniej wydajne niż zwykłe wywołanie, String.valueOf(new Integer(i))które da ten sam rezultat.

Zaletą ""+ijest to, że pisanie jest łatwiejsze / szybsze, a niektórzy ludzie mogą myśleć, że łatwiej jest czytać. Nie jest to zapach kodu, ponieważ nie wskazuje na głębszy problem.

(Odniesienie: JLS 15.8.1 )

Andreas Dolk
źródło
3
Twoje „równoważne” oświadczenie nie jest równoważne. Nawet jeśli wywołanie String.valueOfwymaga boksowania i(nie robi tego, ponieważ istnieje przeciążenie, które je akceptuje int), nie użyłoby tego new Integer(i), użyłoby Integer.valueOf(i). Ale tak naprawdę nic z tego nie robi. Tak new StringBuilder().append("").append(i).toString(), jak zauważa odpowiedź SimonJ. StringBuilder ma własną logikę przekształcania prymitywnej int iw String.
Mark Peters,
4
Część o zapachu kodu jest jednak słuszna; zapach kodu jest tutaj złym terminem. Więc zdejmę głosowanie.
Mark Peters,
Wydaje się nieskuteczne, aby to zrobić za pomocą „” + i. Zalecany jest prosty Integer.toString lub String.valueOf. Zobacz javadevnotes.com/java-integer-to-string-examples
JavaDev
14

Osobiście nie widzę nic złego w tym kodzie.

Jest to bardzo przydatne, gdy chcesz zarejestrować wartość całkowitą, a program rejestrujący akceptuje tylko ciąg. Powiedziałbym, że taka konwersja jest wygodna, gdy trzeba wywołać metodę akceptującą String, ale masz wartość int.

Jeśli chodzi o wybór pomiędzy Integer.toStringalbo String.valueOf, że to wszystko jest kwestią gustu.
... Nawiasem mówiąc , wewnętrznie String.valueOfwywołuje Integer.toStringmetodę. :)

ksu
źródło
12

Innym sposobem, w jaki jestem świadomy, jest od Integerklasy:

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

Konkretny przykład (choć nie sądzę, byś go potrzebował):

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

Działa również na przykład dla innych pierwotnych typów Double.toString.

Zobacz tutaj po więcej szczegółów.

skradać się
źródło
9

Techniki tej nauczono na zajęciach wprowadzających do Java na poziomie licencjackim, które przejęłam dziesięć lat temu. Należy jednak zauważyć, że IIRC nie dotarliśmy jeszcze do metod klasy String i Integer.

Technika jest prosta i szybka w pisaniu. Jeśli wszystko, co robię, to drukuję, użyję tego (na przykład System.out.println("" + i);. Myślę jednak, że nie jest to najlepszy sposób na konwersję, ponieważ potrzeba chwili zastanowienia, aby zrozumieć, co się dzieje, gdy jest używana) w ten sposób. Ponadto, jeśli wydajność jest problemem, wydaje się wolniejsza (więcej poniżej, a także w innych odpowiedziach).

Osobiście wolę Integer.toString (), ponieważ jest oczywiste, co się dzieje. String.valueOf () będzie moim drugim wyborem, ponieważ wydaje się być mylące (obserwuj komentarze po odpowiedzi Darioo).

Tylko na uśmiech :) Napisałem klasy, aby przetestować trzy techniki: „” + i, Integer.toString i String.ValueOf. Każdy test właśnie przekonwertował ints z 1 na 10000 na ciągi. I wtedy każdy biegł przez Linux czasu polecenia pięciokrotnie. Integer.toString () był nieco szybszy niż String.valueOf () raz, wiązały się trzy razy, a String.valueOf () był szybszy raz; różnica nigdy nie była jednak większa niż kilka milisekund.

Technika „” + i była wolniejsza niż obie przy każdym teście, z wyjątkiem jednego, gdy była o 1 milisekundę szybsza niż Integer.toString () i 1 milisekunda wolniejsza niż String.valueOf () (oczywiście w tym samym teście, w którym String.valueOf () był szybszy niż Integer.toString ()). Chociaż zwykle był tylko kilka milisekund wolniejszy, był jeden test, w którym był o około 50 milisekund wolniejszy. YMMV .

GreenMatt
źródło
1
Nie zapomnij wziąć pod uwagę JIT - kilka pierwszych konwersji będzie znacznie wolniejszych i zniekształci taktowanie. Na moim MacBooku konkatenacja zajmuje ~ 20ns dłużej niż dwie pozostałe metody (które obie wymagają ~ 50ns na konwersję), więc różnice, które zauważyłeś w kolejności ms, są prawdopodobnie spowodowane przypadkowym błędem (szeregowanie, przerwania itp.).
SimonJ
6

Istnieją różne sposoby konwersji na ciągi:

StringBuilder string = string.append(i).toString();
String string = String.valueOf(i);
String string = Integer.toString(i);
Shailej Shimpi
źródło
StringBuilder string = string.append (i) .toString (); ... Hm, więc to StringBuilder, czy String? Trochę bałaganu ...
Franta
6

To zależy od tego, jak chcesz użyć swojego ciągu. To może pomóc:

String total =  Integer.toString(123) + Double.toString(456.789);
Niyuhire Justine
źródło
5

To samo dotyczy Simona J. Naprawdę nie lubię idiomu „” + i. Jeśli powiesz String.valueOf (i), Java konwertuje liczbę całkowitą na ciąg znaków i zwraca wynik. Jeśli powiesz „” + i, Java tworzy obiekt StringBuilder, dołącza do niego pusty ciąg, konwertuje liczbę całkowitą na ciąg, dołącza go do StringBuilder, a następnie przekształca StringBuilder na ciąg. To wiele dodatkowych kroków. Przypuszczam, że jeśli zrobisz to raz w dużym programie, to nic wielkiego. Ale jeśli robisz to cały czas, zmuszasz komputer do wykonania dodatkowej pracy i tworzysz te wszystkie dodatkowe obiekty, które następnie trzeba oczyścić. Nie chcę być fanatykiem mikrooptymalizacji, ale nie chcę też niepotrzebnie marnować pieniędzy.

Sójka
źródło
5
String strI = String.valueOf(i);

String string = Integer.toString(i);

Oba sposoby są poprawne.

Shailej Shimpi
źródło
5

Istnieje wiele sposobów konwersji liczby całkowitej na ciąg:

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 Zahidul
źródło
1
String.format ("% d", 1000000) ... To nie jest tak naprawdę Int >> konwersja ciągów, to raczej przetwarzanie ciągów >> tutaj, pomimo przeciążenia. Więc nie polecam tego. Zdecydowanie nie tylko w celu konwersji.
Franta
5

Istnieją trzy sposoby konwersji na ciągi

  1. String string = "" + i;
  2. String string = String.valueOf(i);
  3. String string = Integer.toString(i);
Vihaan Verma
źródło
1
Zapomniałeś: String.format("%d", i).
Brian Goetz
3

Używanie „” + i jest najkrótszym i najprostszym sposobem na konwersję liczby na ciąg. Nie jest to najbardziej wydajny, ale jest najczystszym IMHO i zwykle jest to ważniejsze. Im prostszy kod, tym mniejsze prawdopodobieństwo popełnienia błędu.

Peter Lawrey
źródło
2
Jak popełnić błąd, wywołując String.valueOf lub Integer.toString?
Eva,
1
Natknąłem się na kilka nieidealnych zastosowań String.valueOf (), ale teraz ich nie pamiętam. Chociaż wynik był prawidłowy, był mniej wydajny niż""+i
Peter Lawrey
2

Osobiście uważam, że „” + i wygląda tak, jak w oryginalnym plakacie z pytaniami „śmierdzący”. Użyłem wielu języków OO poza Javą. Jeśli ta składnia ma być odpowiednia, wówczas Java po prostu interpretuje sam i bez potrzeby konwertowania „” w pożądany sposób na ciąg znaków i robi to, ponieważ typ miejsca docelowego jest jednoznaczny, a po prawej stronie zostanie podana tylko jedna wartość . Drugi wydaje się być „sztuczką”, by oszukać kompilator, złe mojo, gdy rozważane są różne wersje Javaca innych producentów lub innych platform, jeśli kod musi kiedykolwiek zostać przeniesiony. Cholera za moje pieniądze, to powinno podobać się wielu innym OOL po prostu weź Typecast: (String) i. mruga

Biorąc pod uwagę mój sposób uczenia się i łatwość zrozumienia takiego konstruktu podczas szybkiego czytania innych kodów, głosuję na metodę Integer.toString (i). Zapominając o ns lub dwóch, w jaki sposób Java implementuje rzeczy w tle vs. String.valueOf (i), ta metoda wydaje mi się słuszna i mówi dokładnie, co się dzieje: mam i Integer i chcę, aby została przekonwertowana na ciąg.

Warto kilkakrotnie podkreślić, że być może po prostu użycie StringBuilder z przodu jest dobrą odpowiedzią na budowanie ciągów mieszanych z tekstem, intami lub innymi obiektami, skoro i tak będzie to używane w tle, prawda?

Tylko moje dwa centy wrzucone w dobrze płatną koteczkę odpowiedzi na pytanie Mansa ... uśmiecha się

EDYTUJ SWOJĄ WŁASNĄ ODPOWIEDŹ PO NIEKTÓRYM ODBICIE:

Ok, Ok, myślałem o tym trochę dłużej, a String.valueOf (i) jest również doskonale dobry i mówi: Chcę String, który reprezentuje wartość liczby całkowitej. lol, angielski jest znacznie trudniejszy do analizy niż Java! Ale pozostawiam resztę odpowiedzi / komentarza ... Zawsze uczono mnie używania najniższego poziomu łańcucha metod / funkcji, jeśli to możliwe, i nadal zachowuje czytelność, więc jeśli String.valueOf wywołuje Integer.toString, to po co używać całej pomarańczy jeśli i tak to obierasz, Hmmm?

Aby wyjaśnić mój komentarz na temat StringBuilder, buduję wiele ciągów z kombinacjami głównie dosłownego tekstu i int, i kończą się długim i brzydkim połączeniem z wyżej wymienionymi procedurami zawartymi między znakami +, więc wydaje mi się, że jeśli zostaną SB i tak się sprzeciwia, a metoda dołączania ma przeciążenia, może być czystsze, aby po prostu iść dalej i użyć go ... Więc myślę, że mam teraz do 5 centów na tym, co? lol...

David
źródło
-1

posługiwać się Integer.toString(tmpInt).trim();

Karan Chunara
źródło
Tak naprawdę nie ma trim()tu żadnej przydatności.
Dorian Gray
-5

Spróbuj prostego rzutowania

char c = (char) i;
Bilal Haider
źródło
3
To nie jest dobry sposób na konwersję int na ciąg. W rzeczywistości nie konwertujesz int na ciąg, konwertujesz int na znak. To zinterpretuje int jako kod znakowy ASCII i da ci ten znak. Jest to niebezpieczne (wartości ujemne itp.) I ogólnie po prostu źle.
Nepoxx,
Wyczyść powyższe pytanie, char i String są różne ...!
ale to działa (zestaw znaków „przesunięcie” ASCII):char c = (char) (i + 48);
electrobabe