Najlepszy sposób na konwersję ArrayList na ciąg

353

Mam coś ArrayList, co chcę wyprowadzić całkowicie jako ciąg. Zasadniczo chcę wyprowadzać go w kolejności, używając toStringkażdego elementu oddzielonego tabulatorami. Czy jest jakiś szybki sposób na to? Możesz przejść przez niego (lub usunąć każdy element) i połączyć go w ciąg znaków, ale myślę, że będzie to bardzo powolne.

Juan Besa
źródło
4
lub usuń każdy element Uważaj, usuwanie elementów z listy ArrayList jest dużym NIE-NIE, ponieważ twoja „pętla” zajmie kwadratowy czas z powodu przesunięcia elementów (pod warunkiem, że zapętlasz od pierwszego do ostatniego elementu).
Dimitry K
To samo dotyczy kolekcji: stackoverflow.com/questions/395401/...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

329

Zasadniczo użycie pętli do iteracji ArrayListjest jedyną opcją:

NIE używaj tego kodu, kontynuuj czytanie na dole tej odpowiedzi, aby zobaczyć, dlaczego nie jest pożądane, i który kod należy zastosować zamiast tego:

ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

String listString = "";

for (String s : list)
{
    listString += s + "\t";
}

System.out.println(listString);

W rzeczywistości konkatenacja łańcuchów będzie w porządku, ponieważ javackompilator zoptymalizuje konkatenację łańcuchów jako serię appendoperacji StringBuilder. Oto część demontażu kodu bajtowego z forpętli z powyższego programu:

   61:  new #13; //class java/lang/StringBuilder
   64:  dup
   65:  invokespecial   #14; //Method java/lang/StringBuilder."<init>":()V
   68:  aload_2
   69:  invokevirtual   #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   72:  aload   4
   74:  invokevirtual   #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   77:  ldc #16; //String \t
   79:  invokevirtual   #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   82:  invokevirtual   #17; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

Jak widać, kompilator optymalizuje tę pętlę za pomocą a StringBuilder, więc wydajność nie powinna być dużym problemem.

(OK, na drugi rzut oka StringBuilderinstancja jest tworzona przy każdej iteracji pętli, więc może nie być najbardziej wydajnym kodem bajtowym. Tworzenie instancji i używanie jawnego StringBuilderprawdopodobnie poprawiłoby wydajność.)

W rzeczywistości myślę, że posiadanie jakiegokolwiek wyjścia (czy to na dysk, czy na ekran) będzie co najmniej o rząd wielkości wolniejsze niż martwienie się o wydajność konkatenacji łańcuchów.

Edycja: Jak wskazano w komentarzach, powyższa optymalizacja kompilatora rzeczywiście tworzy nowe wystąpienie StringBuilderkażdej iteracji. (Które zauważyłem wcześniej.)

Najbardziej zoptymalizowaną techniką do zastosowania będzie odpowiedź Paula Tomblina , ponieważ tworzy ona tylko pojedynczy StringBuilderobiekt poza forpętlą.

Przepisanie powyższego kodu do:

ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

StringBuilder sb = new StringBuilder();
for (String s : list)
{
    sb.append(s);
    sb.append("\t");
}

System.out.println(sb.toString());

Utworzy tylko StringBuilderjedną instancję poza pętlą i wykona tylko dwa wywołania appendmetody wewnątrz pętli, jak pokazano w tym kodzie bajtowym (który pokazuje instancję StringBuilderi pętlę):

   // Instantiation of the StringBuilder outside loop:
   33:  new #8; //class java/lang/StringBuilder
   36:  dup
   37:  invokespecial   #9; //Method java/lang/StringBuilder."<init>":()V
   40:  astore_2

   // [snip a few lines for initializing the loop]
   // Loading the StringBuilder inside the loop, then append:
   66:  aload_2
   67:  aload   4
   69:  invokevirtual   #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   72:  pop
   73:  aload_2
   74:  ldc #15; //String \t
   76:  invokevirtual   #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   79:  pop

Rzeczywiście, optymalizacja ręki powinna być lepsza, ponieważ wnętrze forpętli jest krótsze i nie ma potrzeby tworzenia wystąpienia StringBuilderprzy każdej iteracji.

coobird
źródło
8
Rozważ użycie klasy StringBuilder zamiast dodawania ciągów, ze względu na wydajność.
Jeremy
5
Kompilator zoptymalizuje konkatenację łańcuchów, ale będziesz tworzyć nowy obiekt StringBuilder za każdym razem, gdy pętla zostanie wykonana.
Pedro Henriques
4
-1 dla użycia + =, w tym przypadku jest to zabójca wydajności. Zawsze używaj StringBuilder do wielokrotnego dołączania do łańcucha.
starblue
10
To rozwiązanie dodaje dodatkowe „\ t” na końcu ciągu, co często jest niepożądane, szczególnie gdy chcesz utworzyć listę oddzieloną przecinkami lub podobną. Myślę, że inne opublikowane tutaj rozwiązania, wykorzystujące Apache Commons lub Guava, są lepsze.
Peter Goetz,
3
To nie jest najlepsza odpowiedź. Spójrz poniżej na Vitalii for Javalub Geewax forAndroid
Gibolt
895

W Javie 8 lub nowszej:

String listString = String.join(", ", list);

W przypadku, gdy listnie jest typu String, można użyć łączącego kolektora:

String listString = list.stream().map(Object::toString)
                        .collect(Collectors.joining(", "));
Vitalii Fedorenko
źródło
144
Nie mogę uwierzyć, że dodawanie tego zajęło Java 8.
Paul,
45
Ta odpowiedź powinna zostać poddana większemu głosowaniu! Bez hacków, bibliotek i pętli.
Songo,
4
to nie działa w przypadku tego, co powiedział PO. String.join przyjmuje jako drugi argument Iterable <? rozszerza CharSequence>. Tak to działa, jeśli masz listę <string>, które chcesz zobaczyć, ale jeśli masz List <MyObject> to będzie nie nazywamy toString () w nim jako poszukiwany przez OP
Hilikus
3
Dlaczego, u diabła, nie jest to pierwsza (i zaakceptowana) odpowiedź .. Zawsze muszę przewijać w dół, dopóki nie wiem, że tam jest ... elegancko i zwięźle
Jack
2
Wymaga Android API 26+
Arsen Sench
391

Jeśli robisz to na Androidzie, istnieje przyjemne narzędzie do tego o nazwie TextUtils, które ma .join(String delimiter, Iterable)metodę.

List<String> list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
String joined = TextUtils.join(", ", list);

Oczywiście niewiele poza Androidem, ale pomyślałem, że dodam go do tego wątku ...

JJ Geewax
źródło
1
Ponieważ TextUtils.jointrwa an Object[], zakładam, że wywołuje toString()każdy token. Czy PatientDetailsimplementuje toString()? Jeśli to nie rozwiąże problemu, możesz utknąć, robiąc coś z Separatorklasą.
JJ Geewax
5
org.apache.lang3.StringUtilsrobi praktycznie to samo, więc twoja odpowiedź była dla mnie bardzo przydatna poza Androidem :)
Patrick
1
Popularność tej odpowiedzi (obecnie najlepiej głosowanej) pokazuje, że wiele pytań java pochodzi z rozwoju Androida
Amr H. Abd Elmajeed
1
Mogę się założyć, że zostałeś wysłany na Ziemię, aby rozwiązać mój problem :)
kofoworola
1
Uratowałeś mi życie. <3
Pratik Butani,
234

Pobierz Apache Commons Lang i skorzystaj z metody

 StringUtils.join(list)

 StringUtils.join(list, ", ") // 2nd param is the separator.

Oczywiście możesz to zaimplementować samodzielnie, ale ich kod jest w pełni przetestowany i prawdopodobnie jest to najlepsza możliwa implementacja.

Jestem wielkim fanem biblioteki Apache Commons i uważam również, że jest to świetny dodatek do biblioteki Java Standard Library.

Ravi Wallau
źródło
63
Niestety mieszkańcy SO wolą wynaleźć koło na nowo.
skaffman
33
Również w Apache Commons Lang. Sposób użycia wyglądałby następującoStringUtils.join(list.toArray(),"\t")
Muhd
33
To szczególne koło nie jest warte dodatkowej zależności.
Seva Alekseyev
25
@SevaAlekseyev Myślę, że to dyskusyjne. Jeśli dodasz tę zależność od razu, będziesz korzystał z jej klas znacznie częściej niż nie. Zamiast używać „if string! = Null && string.trim ()! =" ”Użyjesz StringUtils.isNotEmpty ... Użyjesz ObjectUtils.equals (), abyś nie musiał wszędzie sprawdzać null. Ale jeśli poczekasz na jedyną zależność, która uzasadnia korzystanie z tych bibliotek, możesz ich nigdy nie używać
Ravi Wallau
6
Fajnie też, że nie doda dodatkowej zakładki na końcu!
keuleJ
139

To dość stare pytanie, ale myślę, że równie dobrze mogę dodać bardziej nowoczesną odpowiedź - skorzystaj z Joinerklasy z Guawy :

String joined = Joiner.on("\t").join(list);
Jon Skeet
źródło
2
To jest moje ulubione rozwiązanie. : -> +1 dla guawy.
csgeek
Ctrl + F również dla Guawy. Dzięki!
Priidu Neemre
List <String> list = new ArrayList <String> (); list.add („Cześć”); list.add („Hai”); list.add („Cześć”); System.out.println (list.toString (). Substring (1, list.toString (). Length () - 1) .replaceAll (",", "\ t"));
Lova Chittumuri
86

Zmiana listy na czytelny i znaczący ciąg znaków jest tak naprawdę częstym pytaniem, z którym każdy może się spotkać.

Przypadek 1 . Jeśli masz aplet StringUtils na swojej ścieżce klasy (jak z rogerdpack i Ravi Wallau):

import org.apache.commons.lang3.StringUtils;
String str = StringUtils.join(myList);

Przypadek 2 . Jeśli chcesz korzystać tylko z JDK (7):

import java.util.Arrays;
String str = Arrays.toString(myList.toArray()); 

Po prostu nigdy nie buduj samodzielnie kół, nie używaj pętli do tego zadania w jednej linii.

Sheng.W
źródło
1
Nie zauważyłem twojego rozwiązania Case 2 przed opublikowaniem własnego. Twoja jest rzeczywiście znacznie lepsza i oszczędza dodatkowy krok. Zdecydowanie poleciłbym to nad niektórymi odpowiedziami, które wydają się wymagać dodatkowych narzędzi.
Elliander
5
Arrays.toString(myList.toArray())- najłatwiejsze i najprostsze rozwiązanie
Ondrej Bozek
Myślę, że należy to uznać za najlepsze i najbardziej wydajne rozwiązanie
Morey,
Arrays.toString(list.toArray())jest łatwy do napisania, ale wysoce nieefektywny.
Matthieu,
60

Jeśli szukałeś szybkiego jednuliniowego oprogramowania, od wersji Java 5 możesz to zrobić:

myList.toString().replaceAll("\\[|\\]", "").replaceAll(", ","\t")

Dodatkowo, jeśli Twoim celem jest jedynie wydrukowanie zawartości i nie martwisz się o „\ t”, możesz po prostu to zrobić:

myList.toString()

który zwraca ciąg podobny do

[str1, str2, str3]

Jeśli masz tablicę (nie ArrayList), możesz wykonać to samo:

 Arrays.toString(myList).replaceAll("\\[|\\]", "").replaceAll(", ","\t")
Ken Shih
źródło
3
Myślę, że jest to faktycznie bardziej wydajne niż metody zamieszczone powyżej. Taki wstyd pokazany jest na dole. To może nie być eleganckie, ale mocno wierzę, że twoje rozwiązanie działa O (n), podczas gdy inne teoretycznie działają w O (n ^ 2) (ponieważ ciągi Java są niezmienne, w zasadzie tworzysz nowy Ciąg przy każdym scaleniu, a staje się gorzej wynikowy ciąg staje się większy)
user3790827 15.04.16
Jeśli twój tekst jest bardzo duży, w końcu zjadasz zasoby komputera.
user3790827,
Ta metoda jest 7-8 razy wolniejsza niż przy użyciu StringBuilder.
Zoka
@ user3790827 Patrzysz na bardzo powierzchowny poziom. Jeśli powiem ci, abyś szukał osoby w mgospodarstwach domowych w nmiastach w xstanach, powiedziałbyś, że to O(mnx)lub O(n^3), ale mogę to przeformułować, aby powiedzieć „szukaj tej osoby w tym kraju”, i natychmiast byś mi powiedział O(n). Ponadto wszystkie algorytmy tutaj są generalnie O(n), nie ma pętli w pętli.
Jai
39

Pętlę i wywoływanie toString. Nie ma magicznego sposobu, a jeśli tak, to co, według niego, działałoby pod przykryciem innym niż przechodzenie przez niego? Jedyną mikrooptymalizacją byłoby użycie StringBuilder zamiast String, a nawet to nie jest ogromna wygrana - łączenie łańcuchów zamienia się w StringBuilder pod przykryciem, ale przynajmniej jeśli napiszesz to w ten sposób, zobaczysz, co się dzieje.

StringBuilder out = new StringBuilder();
for (Object o : list)
{
  out.append(o.toString());
  out.append("\t");
}
return out.toString();
Paul Tomblin
źródło
Dzięki! to właśnie robię :)
Juan Besa
4
W przypadku dużych tablic zdecydowanie nie jest to mikrooptymalizacja. Automatyczna konwersja do użycia StringBuilder jest wykonywana osobno dla każdej konkatenacji łańcucha, co nie pomaga w przypadku pętli. Jest OK, jeśli połączysz dużą liczbę elementów w jednym wyrażeniu.
starblue
1
Bezpośrednie użycie StringBuilder to wielka sprawa, jeśli łączysz powiedzmy, że 50 000 ciągów daje ~ 1 MB ciągu wynikowego - może to być różnica 1 minuty w porównaniu z czasem wykonania 1 s.
Pan Napik,
36

Większość projektów Java ma często dostępny język apache-commons. Metody StringUtils.join () są bardzo ładne i mają kilka smaków, które zaspokoją prawie każdą potrzebę.

public static java.lang.String join(java.util.Collection collection,
                                    char separator)


public static String join(Iterator iterator, String separator) {
    // handle null, zero and one elements before building a buffer 
    Object first = iterator.next();
    if (!iterator.hasNext()) {
        return ObjectUtils.toString(first);
    }
    // two or more elements 
    StringBuffer buf = 
        new StringBuffer(256); // Java default is 16, probably too small 
    if (first != null) {
        buf.append(first);
    }
    while (iterator.hasNext()) {
        if (separator != null) {
            buf.append(separator);
        }
        Object obj = iterator.next();
        if (obj != null) {
            buf.append(obj);
        }
    }
    return buf.toString();
}

Parametry:

kolekcja - zbiór wartości do połączenia, może być zerowy

separator - znak separatora do użycia

Zwroty : połączony ciąg, null, jeśli iterator jest pusty

Od: 2.3

Brian
źródło
2
Jest to bardzo miłe, ponieważ join(...)metoda ma warianty zarówno dla tablic, jak i kolekcji.
vikingsteve
Musiałem stworzyć kolekcje ciągów z rzadko zapełnianymi elementami, z losowymi liczbami. Na koniec potrzebowałem łańcucha, a nie tablicy, a nie tablicy do łańcucha. To jest mój kod: Collections.shuffle (L); StringBuilder sb = new StringBuilder (); L.forEach (e -> sb.append (e)); return sb.toString ();
dobrivoje
14

W tym prostym przypadku użycia możesz po prostu połączyć ciągi przecinkiem. Jeśli używasz Java 8:

String csv = String.join("\t", yourArray);

w przeciwnym razie commons-lang ma metodę join ():

String csv = org.apache.commons.lang3.StringUtils.join(yourArray, "\t");
Khader MA
źródło
13

Eleganckim sposobem radzenia sobie z końcowymi znakami separacji jest użycie separatora klas

StringBuilder buf = new StringBuilder();
Separator sep = new Separator("\t");
for (String each: list) buf.append(sep).append(each);
String s = buf.toString();

Metoda toString klasy Separator zwraca separator, z wyjątkiem pierwszego wywołania. Dlatego drukujemy listę bez końcowych (lub w tym przypadku) wiodących separatorów.

akuhn
źródło
8

W Javie 8 jest to proste. Zobacz przykład listy liczb całkowitych:

String result = Arrays.asList(1,2,3).stream().map(Object::toString).reduce((t, u) -> t + "\t" + u).orElse("");

Lub wersja wielowierszowa (łatwiejsza do odczytania):

String result = Arrays.asList(1,2,3).stream()
    .map(Object::toString)
    .reduce((t, u) -> t + "\t" + u)
    .orElse("");

Aktualizacja - krótsza wersja

String result = Arrays.asList(1,2,3).stream()
                .map(Object::toString)
                .collect(Collectors.joining("\t"));
amra
źródło
2
To może być tylko wiersz kodu, ale dla mnie to nie wygląda na proste. Dla mnie przemierzanie Listy i parsowanie jej elementów w Ciąg jest prostsze niż to.
Bartzilla,
1
To też było moje pierwsze wrażenie. Ale kiedy się do tego przyzwyczaiłem, wydaje mi się to niesamowite. Na przykład możesz dodać operacje takie jak filter. W końcu znacznie łatwiej jest mi odczytać kod.
amra
3
W Javie 8: String.join ("\ t", tablica)
Tomasz
Ostatni komentarz działa tylko wtedy, gdy treść jest Stringrównież. Jeśli jest to lista z Integerktórymi masz problem
LeO
Wszystkie 3 z nich wymagają poziomu interfejsu API 24 na Androidzie.
Asad35Waheed
6

To jest O(n) algorytm w obu kierunkach (chyba że wykonałeś jakieś wielowątkowe rozwiązanie, w którym podzieliłeś listę na wiele list podrzędnych, ale nie sądzę, że o to prosisz).

Po prostu użyj StringBuilderponiższego:

StringBuilder sb = new StringBuilder();

for (Object obj : list) {
  sb.append(obj.toString());
  sb.append("\t");
}

String finalString = sb.toString();

StringBuilderBędzie dużo szybciej niż ciąg konkatenacji, ponieważ nie będzie ponowne utworzenie wystąpienia Stringobiektu na każdej konkatenacji.

Mike C.
źródło
5

Jeśli zdarzyło Ci się być na Androidzie i jeszcze nie używasz Jacka (np. Ponieważ wciąż brakuje wsparcia dla Instant Run) i jeśli chcesz mieć większą kontrolę nad formatowaniem wynikowego łańcucha (np. Chciałbyś użyć znaku nowej linii jako dzielnik elementów) i zdarzyło się użyć / chcesz użyć biblioteki StreamSupport (do korzystania ze strumieni w Javie 7 lub wcześniejszych wersjach kompilatora), możesz użyć czegoś takiego (umieściłem tę metodę w mojej klasie ListUtils):

public static <T> String asString(List<T> list) {
    return StreamSupport.stream(list)
            .map(Object::toString)
            .collect(Collectors.joining("\n"));
}

I oczywiście upewnij się, że zaimplementowałeś toString () w klasie obiektów listy.

Javad Sadeqzadeh
źródło
1
Użycie reducejest wyjątkowo nieefektywne w przypadku konkatenacji ciągów. Powinieneś to zrobić w sposób return StreamSupport.stream(list).map(Object::toString).collect(joining("\n"))używany w Javie 8 StringJoiner. Nie ma powodu, dla którego nie można tego zrobić również z obsługą streamingu .
Stefan Zobel
Inną rzeczą jest to, że Twój kod poniósłby się okropnie (z powodu Optional#get), gdyby otrzymał pustą listę.
Stefan Zobel
@StefanZobel Dziękujemy za zwrócenie uwagi na wydajność i problemy ze skrzynkami. Zmodyfikowałem kod.
Javad Sadeqzadeh
3

Jeśli nie chcesz ostatniego \ t po ostatnim elemencie, musisz użyć indeksu do sprawdzenia, ale pamiętaj, że to „działa” (tj. O (n)), gdy listy implementują RandomAccess.

List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

StringBuilder sb = new StringBuilder(list.size() * apprAvg); // every apprAvg > 1 is better than none
for (int i = 0; i < list.size(); i++) {
    sb.append(list.get(i));
    if (i < list.size() - 1) {
        sb.append("\t");
    }
}
System.out.println(sb.toString());

źródło
3

Poniższy kod może ci pomóc,

List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
String str = list.toString();
System.out.println("Step-1 : " + str);
str = str.replaceAll("[\\[\\]]", "");
System.out.println("Step-2 : " + str);

Wynik:

Step-1 : [1, 2, 3]
Step-2 : 1, 2, 3
Srinivasan.S
źródło
3

Może nie być najlepszy, ale elegancki sposób.

Arrays.deepToString (Arrays.asList („Test”, „Test2”)

import java.util.Arrays;

    public class Test {
        public static void main(String[] args) {
            System.out.println(Arrays.deepToString(Arrays.asList("Test", "Test2").toArray()));
        }
    }

Wynik

[Test, Test2]

Mohan Narayanaswamy
źródło
1
Myślę, że to najlepszy sposób, jeśli „najlepszy” oznacza czytelność kodu. Nie spojrzałem na kod, ale prawdopodobnie jest on tak samo skuteczny jak metoda StringBuilder (prawdopodobnie używa StringBuilder pod maską), chociaż nie jest tak dostosowywalny w danych wyjściowych.
Mike Miller,
3

Czy byłoby coś dobrego:

List<String> streamValues = new ArrayList<>();
Arrays.deepToString(streamValues.toArray()));   
Beezer
źródło
3

Jeśli korzystasz z kolekcji Eclipse , możesz użyć tej makeString()metody.

ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

Assert.assertEquals(
    "one\ttwo\tthree",
    ArrayListAdapter.adapt(list).makeString("\t"));

Jeśli możesz przekonwertować swój ArrayListna FastList, możesz pozbyć się adaptera.

Assert.assertEquals(
    "one\ttwo\tthree",
    FastList.newListWith("one", "two", "three").makeString("\t"));

Uwaga: jestem osobą odpowiedzialną za kolekcje Eclipse.

Craig P. Motlin
źródło
3
List<String> stringList = getMyListOfStrings();
StringJoiner sj = new StringJoiner(" ");
stringList.stream().forEach(e -> sj.add(e));
String spaceSeparated = sj.toString()

Przechodzisz do new StringJoinersekwencji char, której chcesz użyć jako separatora. Jeśli chcesz zrobić plik CSV:new StringJoiner(", ");

fmsf
źródło
3

W jednej linii: od [12,0,1,78,12] do 12 0 1 78 12

String srt= list.toString().replaceAll("\\[|\\]|,","");
Pratyush Pranjal
źródło
2
1) Nie ma już powodu, aby używać takiego kodu (jak 4 lata temu!). 2) Ta odpowiedź nie dodaje niczego do pytań i odpowiedzi.
Radiodef,
5 gwiazdek w jednej linii. wielkie dzięki.
Atef Farouk
To działa idealnie. W przypadku łańcucha rozdzielanego przecinkami użyj: String srt = list.toString (). ReplaceAll ("\ [| \]", "");
Asad35Waheed
2

Do oddzielania za pomocą zakładek zamiast println możesz użyć print

ArrayList<String> mylist = new ArrayList<String>();

mylist.add("C Programming");
mylist.add("Java");
mylist.add("C++");
mylist.add("Perl");
mylist.add("Python");

for (String each : mylist)
{       
    System.out.print(each);
    System.out.print("\t");
}
kotlety
źródło
1

Widzę kilka przykładów, które zależą od dodatkowych zasobów, ale wydaje się, że byłoby to najprostsze rozwiązanie: (tego właśnie użyłem w swoim własnym projekcie), który w zasadzie jest po prostu konwertowany z ArrayList na Array, a następnie na Listę .

    List<Account> accounts = new ArrayList<>();

   public String accountList() 
   {
      Account[] listingArray = accounts.toArray(new Account[accounts.size()]);
      String listingString = Arrays.toString(listingArray);
      return listingString;
   }
Elliander
źródło
0

To już dość stara rozmowa, a wspólne apache używają teraz StringBuilder wewnętrznie: http://commons.apache.org/lang/api/src-html/org/apache/commons/lang/StringUtils.html#line. 3045

Jak wiemy, poprawi to wydajność, ale jeśli wydajność ma kluczowe znaczenie, zastosowana metoda może być nieco nieefektywna. Chociaż interfejs jest elastyczny i pozwoli na spójne zachowanie różnych typów kolekcji, jest on nieco nieefektywny w przypadku list, co jest rodzajem kolekcji w pierwotnym pytaniu.

Opieram to na tym, że ponosimy pewne koszty ogólne, których unikalibyśmy, po prostu iterując elementy w tradycyjnej pętli for. Zamiast tego za kulisami dzieją się pewne dodatkowe rzeczy, które sprawdzają, czy są równoległe modyfikacje, wywołania metod itp. Ulepszona pętla for spowoduje z drugiej strony ten sam narzut, ponieważ iterator jest używany na obiekcie Iterable (List).

Alex VI
źródło
0

Możesz do tego użyć Regex. To jest tak zwięzłe, jak to możliwe

System.out.println(yourArrayList.toString().replaceAll("\\[|\\]|[,][ ]","\t"));
Vikrant Goel
źródło
-1

A co z tą funkcją:

public static String toString(final Collection<?> collection) {
    final StringBuilder sb = new StringBuilder("{");
    boolean isFirst = true;
    for (final Object object : collection) {
        if (!isFirst)
            sb.append(',');
        else
            isFirst = false;
        sb.append(object);
    }
    sb.append('}');
    return sb.toString();
}

działa dla każdego rodzaju kolekcji ...

programista Androida
źródło