Mam listę liczb całkowitych List<Integer>
i chciałbym przekonwertować wszystkie obiekty typu integer na ciągi, kończąc w ten sposób na nowym List<String>
.
Oczywiście mógłbym utworzyć nową List<String>
i zapętlić listę wywołującą String.valueOf()
każdą liczbę całkowitą, ale zastanawiałem się, czy istnieje lepszy (czytaj: bardziej automatyczny ) sposób zrobienia tego?
java
string
collections
integer
ChrisThomas123
źródło
źródło
Korzystając z Google Collections z Guava-Project , można użyć
transform
metody z klasy ListsList
Zwrócony przeztransform
to widok na liście podkładowej - transformacja będzie stosowana na każdym wejściu do przekształconej listy.Należy pamiętać, że po zastosowaniu do wartości null
Functions.toStringFunction()
zostanie wyrzucony aNullPointerException
, więc używaj go tylko wtedy, gdy masz pewność, że lista nie będzie zawierać wartości null.źródło
Rozwiązanie dla Java 8. Trochę dłuższe niż Guava, ale przynajmniej nie musisz instalować biblioteki.
źródło
toString
, kończy się to krócej w przypadku konwersji nieobsługiwanych przez bibliotekę funkcji Guava. Funkcje niestandardowe są nadal łatwe, ale zawiera znacznie więcej kodu niż ten strumień Java 8To, co robisz, jest w porządku, ale jeśli czujesz potrzebę „Java-it-up”, możesz użyć Transformera i metody zbierania z Apache Commons , np .:
..i wtedy..
źródło
Źródło String.valueOf pokazuje to:
Nie żeby to miało duże znaczenie, ale użyłbym toString.
źródło
Zamiast używać String.valueOf użyłbym .toString (); pozwala uniknąć niektórych automatycznych boksów opisanych przez @ johnathan.holland
Javadoc mówi, że valueOf zwraca to samo co Integer.toString ().
źródło
Oto jedno-liniowe rozwiązanie bez oszukiwania z biblioteką inną niż JDK.
źródło
Kolejne rozwiązanie wykorzystujące Guava i Java 8
źródło
Nie jest to rdzeń Java i nie jest to ogólna wersja, ale popularna biblioteka Jakarta commons zawiera kilka przydatnych abstrakcji dla tego rodzaju zadań. W szczególności zapoznaj się z metodami zbierania danych
CollectionUtils
Coś do rozważenia, jeśli już korzystasz z kolekcji Common w swoim projekcie.
źródło
Osobom zaniepokojonym „boksem” jsight odpowiada: nie ma.
String.valueOf(Object)
jest tutaj używany i nigdy nieint
jest wykonywane rozpakowywanie .Czy używasz,
Integer.toString()
czyString.valueOf(Object)
zależy od tego, jak chcesz obsłużyć możliwe wartości null. Chcesz zgłosić wyjątek (prawdopodobnie), czy mieć na liście ciągi „zerowe” (być może). Jeśli pierwszy, chcesz wrzucićNullPointerException
jakiś inny typ?Jedna mała wada w odpowiedzi jsight:
List
jest to interfejs, nie możesz na nim użyć nowego operatora.java.util.ArrayList
W tym przypadku prawdopodobnie użyłbym litery a, zwłaszcza, że z góry wiemy, jak długa może być lista.źródło
źródło
@Jonathan: Mogę się mylić, ale uważam, że String.valueOf () w tym przypadku wywoła funkcję String.valueOf (Object), zamiast zostać zapakowaną w String.valueOf (int). String.valueOf (Object) po prostu zwraca „null”, jeśli ma wartość null, lub wywołuje Object.toString (), jeśli nie jest równe null, co nie powinno obejmować boksu (chociaż oczywiście wymaga to tworzenia nowych obiektów łańcuchowych).
źródło
Myślę, że użycie Object.toString () w jakimkolwiek celu innym niż debugowanie jest prawdopodobnie naprawdę złym pomysłem, nawet jeśli w tym przypadku oba są funkcjonalnie równoważne (zakładając, że lista nie ma wartości null). Deweloperzy mogą dowolnie zmieniać zachowanie dowolnej metody toString () bez żadnego ostrzeżenia, w tym metod toString () dowolnych klas w bibliotece standardowej.
Nie martw się nawet o problemy z wydajnością spowodowane procesem pakowania / rozpakowywania. Jeśli wydajność jest krytyczna, po prostu użyj macierzy. Jeśli jest to naprawdę ważne, nie używaj Javy. Próba przechytrzenia JVM doprowadzi tylko do bólu serca.
źródło
Odpowiedź tylko dla ekspertów:
źródło
String
) będzie korzystać z tej samej tablicy bazowej (odall
), więc faktycznie będzie całkiem wydajna pod względem pamięci, co byłoby ważne dla długoterminowej wydajności. Chyba że chcesz zachować tylko jeden z elementów, oczywiście ...Lambdaj pozwala to zrobić w bardzo prosty i czytelny sposób. Na przykład, zakładając, że masz listę liczb całkowitych i chcesz przekonwertować je na odpowiednią reprezentację typu String, możesz napisać coś takiego;
Lambdaj stosuje funkcję konwersji tylko podczas iteracji wyniku.
źródło
Nie da się uniknąć „kosztu boksu”; Faux generyczne kontenery Java mogą przechowywać tylko obiekty, więc twoje int muszą być umieszczone w pudełkach w liczbach całkowitych. W zasadzie mógłby uniknąć downcast z Object do Integer (ponieważ jest to bezcelowe, ponieważ Object jest wystarczająco dobry zarówno dla String.valueOf, jak i Object.toString), ale nie wiem, czy kompilator jest wystarczająco inteligentny, aby to zrobić. Konwersja ze String na Object powinna być mniej więcej bezczynna, więc nie byłbym skłonny się tym martwić.
źródło
Możemy użyć iteratora, aby osiągnąć to samo.
źródło
Korzystanie ze strumieni: jeśli powiedzmy, że wynikiem jest lista liczb całkowitych (
List<Integer> result
), to:Jeden ze sposobów rozwiązania tego problemu. Mam nadzieję że to pomoże.
źródło
Nieco bardziej zwięzłe rozwiązanie wykorzystujące metodę forEach z oryginalnej listy:
źródło
Dla zabawy, rozwiązanie wykorzystujące framework jsr166y fork-join, które powinno być w JDK7.
(Zastrzeżenie: nieskompilowane. Specyfikacja nie jest sfinalizowana. Itp.)
Jest mało prawdopodobne, aby w JDK7 było trochę wnioskowania o typie i cukru składniowego, aby uczynić to z wywołaniem Mapping mniej szczegółowym:
źródło
To jest tak podstawowa rzecz do zrobienia, że nie użyłbym zewnętrznej biblioteki (spowoduje to zależność w twoim projekcie, której prawdopodobnie nie potrzebujesz).
Mamy klasę metod statycznych stworzonych specjalnie do tego typu zadań. Ponieważ kod jest tak prosty, pozwalamy Hotspotowi przeprowadzić optymalizację za nas. Wydaje się, że jest to ostatnio motyw w moim kodzie: pisz bardzo prosty (bezpośredni) kod i pozwól Hotspotowi wykonać swoją magię. Rzadko mamy problemy z wydajnością związane z takim kodem - gdy pojawi się nowa wersja maszyny wirtualnej, uzyskasz wszystkie dodatkowe korzyści związane z prędkością itp.
Chociaż uwielbiam kolekcje Dżakarty, nie obsługują one Generics i używają 1.4 jako wyświetlacza LCD. Obawiam się kolekcji Google, ponieważ są one wymienione jako poziom pomocy Alfa!
źródło
Chciałem tylko zająć się rozwiązaniem problemu zorientowanym obiektowo.
Jeśli modelujesz obiekty domeny, rozwiązanie znajduje się w obiektach domeny. Domena tutaj to lista liczb całkowitych, dla których chcemy mieć wartości łańcuchowe.
Najłatwiej byłoby w ogóle nie konwertować listy.
Biorąc to pod uwagę, aby przekonwertować bez konwersji, zmień oryginalną listę liczb całkowitych na listę wartości, gdzie wartość wygląda mniej więcej tak ...
Będzie to szybsze i zajmie mniej pamięci niż kopiowanie listy.
Powodzenia!
źródło