Pracuję nad projektem, w którym wszystkie konwersje od int
do String
są 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ę?
java
string
type-conversion
Denis Palnicki
źródło
źródło
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.Odpowiedzi:
Normalne sposoby byłyby
Integer.toString(i)
lubString.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:
w czasie kompilacji. Jest nieco mniej wydajny (
sb.append()
kończy się sprawdzanieInteger.getChars()
, co i takInteger.toString()
by zrobił), ale działa.Aby odpowiedzieć na komentarz Grodrigueza: ** Nie, kompilator nie optymalizuje w tym przypadku pustego ciągu - spójrz:
Zainicjuj StringBuilder:
Dołącz pusty ciąg:
Dołącz liczbę całkowitą:
Wyodrębnij ostatni ciąg:
Istnieje propozycja i trwają prace nad zmianą tego zachowania, ukierunkowane na JDK 9.
źródło
"" + 5
Staje się"5"
)."" + 5
zamiast tego"5"
?"" + integer
Podejście jest stosowane w jednym z urzędowych tutoriali oracle .Jest do przyjęcia, ale nigdy czegoś takiego nie napisałem. Wolałbym to:
źródło
NumberFormatter
jest. Możesz używać formatów takich jakNumberFormat.getInstance(Locale.FRENCH)
.To nie jest dobry sposób.
Podczas konwersji z int na string należy użyć:
źródło
int i
dostać zapakowane doInteger
przed uzyskiwanie dodany doString strI
?StringBuilder.append(int)
(iStringBuilder
maappend
metodę dla wszystkich typów pierwotnych).To nie tylko optymalizacja 1 . Nie lubie
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:
Lub, nie mój preferowany, ale wciąż lepszy niż konkatenacja, uzyskaj reprezentację ciągu obiektu (liczba całkowita):
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);
lubString id = "ID" + i;
źródło
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.
źródło
Ekspresja
prowadzi do konwersji łańcucha z
i
przy starcie. Ogólny typ wyrażenia toString
.i
jest najpierw konwertowany naInteger
obiekt (new Integer(i)
), a następnieString.valueOf(Object obj)
wywoływany. Jest to więc równoważne zOczywiście jest to nieco mniej wydajne niż zwykłe wywołanie,
String.valueOf(new Integer(i))
które da ten sam rezultat.Zaletą
""+i
jest 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 )
źródło
String.valueOf
wymaga boksowaniai
(nie robi tego, ponieważ istnieje przeciążenie, które je akceptujeint
), nie użyłoby tegonew Integer(i)
, użyłobyInteger.valueOf(i)
. Ale tak naprawdę nic z tego nie robi. Taknew StringBuilder().append("").append(i).toString()
, jak zauważa odpowiedź SimonJ. StringBuilder ma własną logikę przekształcania prymitywnej inti
w String.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.toString
alboString.valueOf
, że to wszystko jest kwestią gustu.... Nawiasem mówiąc , wewnętrznie
String.valueOf
wywołujeInteger.toString
metodę. :)źródło
Innym sposobem, w jaki jestem świadomy, jest od
Integer
klasy:Konkretny przykład (choć nie sądzę, byś go potrzebował):
Działa również na przykład dla innych pierwotnych typów
Double.toString
.Zobacz tutaj po więcej szczegółów.
źródło
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 .
źródło
Istnieją różne sposoby konwersji na ciągi:
źródło
To zależy od tego, jak chcesz użyć swojego ciągu. To może pomóc:
źródło
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.
źródło
Oba sposoby są poprawne.
źródło
Istnieje wiele sposobów konwersji liczby całkowitej na ciąg:
1)
2)
3)
4)
źródło
Istnieją trzy sposoby konwersji na ciągi
String string = "" + i;
String string = String.valueOf(i);
String string = Integer.toString(i);
źródło
String.format("%d", i)
.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.
źródło
""+i
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...
źródło
posługiwać się
Integer.toString(tmpInt).trim();
źródło
trim()
tu żadnej przydatności.Spróbuj prostego rzutowania
źródło
char c = (char) (i + 48);