Jak przekonwertować ciąg rozdzielany przecinkami na ArrayList?

538

Czy jest jakaś wbudowana metoda w Javie, która pozwala nam konwertować ciąg znaków rozdzielany przecinkami na jakiś kontener (np. Tablicę, listę lub wektor)? Czy też muszę do tego napisać niestandardowy kod?

String commaSeparated = "item1 , item2 , item3";
ArrayList<String> items = //method that converts above string into list??
Jame
źródło
Jeśli chcesz przeanalizować plik CSV, zobacz stackoverflow.com/questions/3908012/parsing-csv-in-java
Raedwald
@ Raedwald Nie o to jednak poprosił OP
Crowie
3
TYLKO odpowiedź ColinD jest tutaj poprawna, zakładając, że chcesz ArrayList jak w tytule pytania. ArrayList (który można modyfikować) jest całkowicie różny od List, który może być zwykłą ustaloną listą.
Fattie,
@Fattie - fair point, i naprawiłem to - stackoverflow.com/a/34735419/744133
YoYo
1
Rozwiązanie Java 8: stackoverflow.com/a/46485179/1216775
akhil_mittal

Odpowiedzi:

1016

Konwertuj łańcuch rozdzielony przecinkami na listę

List<String> items = Arrays.asList(str.split("\\s*,\\s*"));

Powyższy kod dzieli ciąg na separator zdefiniowany jako:, zero or more whitespace, a literal comma, zero or more whitespacektóry umieści słowa na liście i zwinie wszelkie spacje między słowami a przecinkami.


Pamiętaj, że to zwraca po prostu opakowanie w tablicy: NIE MOŻESZ na przykład .remove()wynikać z wynikowego List. W rzeczywistości ArrayListmusisz dalej korzystać new ArrayList<String>.

AlexR
źródło
39
@rosch Jest to wyrażenie regularne (regex). \spasuje do dowolnej białej spacji, *stosuje dopasowanie zero lub więcej razy. \s*Oznacza to więc „dopasuj dowolną białą spację zero lub więcej razy”. Szukamy tego przed i po przecinku. Dlatego podział będzie działał dla ciągów takich jak "item1 , item2 , item3", "item1,item2 ,item3"itp. W Javie musisz uciec przed odwrotnym ukośnikiem w ciągach, więc otrzymasz\\s*
andrewrjones
9
Proponuję użyć "[\\s,]+"do przycięcia białych znaków dla wartości. Na przykład " item1 , item2 , item3 , "staje się ["item1", "item2", "item3"].
Andrii Nemchenko
5
"[\\s,]+"podzieli się również na przestrzeń wewnętrzną w tokenie oddzielonym przecinkami, potraktuje obie białe znaki jako separator, nawet gdy przecinek nie jest obecny, zamiast przecinka plus dowolna liczba otaczających białych znaków. "\\s*(,\\s*)+"przycina białe znaki tylko wokół tokenów oddzielonych przecinkami, a także ignoruje ciągi znaków, które są tylko białymi lub pustymi znakami.
theferrit32
2
Na marginesie: jeśli spodziewasz się uzyskać pustą listę w przypadku pustego ciągu wejściowego, ta metoda nie pasuje do twojego przypadku użycia. Otrzymasz listę z 1 elementem zawierającym pusty ciąg znaków.
Madis Pukkonen,
3
@AlexR Chociaż doceniam, że szanujecie OP, ale powstrzymałbym się od mówienia takich rzeczy. Znam ludzi, którzy źle się czują, gdy nie spełniają oczekiwań ludzi, gdy są fałszywie chwaleni. Tylko myśl.
199

Arrays.asListzwraca stały rozmiar Listwspierany przez tablicę. Jeśli chcesz normalnego mutable java.util.ArrayList, musisz to zrobić:

List<String> list = new ArrayList<String>(Arrays.asList(string.split(" , ")));

Lub za pomocą Guava :

List<String> list = Lists.newArrayList(Splitter.on(" , ").split(string));

Użycie a Splitterdaje większą elastyczność w dzieleniu łańcucha i daje możliwość, na przykład, pomijania pustych łańcuchów w wynikach i przycinania wyników. Ma również mniej dziwne zachowanie niż String.splitnie wymaga dzielenia przez regex (to tylko jedna opcja).

ColinD
źródło
6
Wolałby Splitter.on (","). TrimResults (). Split (string), chociaż widzę, że o tym wspomniałeś. więc +1
Jan B
10
+1 za wskazanie, że Arrays.asList nie zwraca normalnej listy. Jeśli spróbujesz dodać lub usunąć element z tej listy, otrzymasz UnsupportedOperationException.
Alfredo Osorio,
9
Guava ma teraz to od (15.0): Splitter.on (","). SplitToList (string) . Oszczędza mały krok.
Kango_V
Czy jest jakiś sposób na dodanie pustych wartości w String iike, jeśli mam String w ten sposób: 1,, 3,4,5 tutaj 2 brakuje / jest pusty. Podczas konwersji na liście 2 przeskoczy. Ale chcę dodać to jako pustą wartość.
A.Aleem11
Problem z tą implementacją i kilkoma innymi podobnymi przykładami polega na tym, że chociaż Arrays.asListzapewnia ona owijanie wokół natywnej tablicy (unikając kopiowania elementu), new ArrayList(...)dokładnie wykona taką kopię element po elemencie. Prawdopodobnie powinniśmy preferować podejście, które pozwala na bezpośrednie dodawanie przeanalizowanych elementów do pożądanej kolekcji docelowej.
YoYo
70

Dwa kroki:

  1. String [] items = commaSeparated.split("\\s*,\\s*");
  2. List<String> container = Arrays.asList(items);
duffymo
źródło
1
Po wstawieniu zmiennej items jest ona zasadniczo taka sama jak inne odpowiedzi, ale w rzeczywistości jest nieco bardziej wydajna, ponieważ nie używa wyrażenia regularnego. Z drugiej strony spacje wokół przecinka zabiją tę opcję.
Amrinder Arora,
2
@AmrinderArora argument do splitjest interpretowany jako RegEx.
Madbreaks
23

Oto kolejny sposób konwersji CSV na ArrayList:

String str="string,with,comma";
ArrayList aList= new ArrayList(Arrays.asList(str.split(",")));
for(int i=0;i<aList.size();i++)
{
    System.out.println(" -->"+aList.get(i));
}

Drukuje cię

-> ciąg
-> z
-> przecinek

Arvindvp6
źródło
21

Jeśli a Listjest celem końcowym, jak stwierdził PO, to już zaakceptowana odpowiedź jest wciąż najkrótsza i najlepsza. Chciałbym jednak przedstawić alternatywne rozwiązania wykorzystujące strumienie Java 8 , które przyniosą więcej korzyści, jeśli będą częścią potoku do dalszego przetwarzania.

Zawijając wynik funkcji .split (macierz macierzysta) do strumienia, a następnie konwertując na listę.

List<String> list =
  Stream.of("a,b,c".split(","))
  .collect(Collectors.toList());

Jeśli ważne jest, aby wynik był zapisany jak ArrayListw tytule z PO, możesz użyć innej Collectormetody:

ArrayList<String> list = 
  Stream.of("a,b,c".split(","))
  .collect(Collectors.toCollection(ArrayList<String>::new));

Lub używając interfejsu analizującego RegEx:

ArrayList<String> list = 
  Pattern.compile(",")
  .splitAsStream("a,b,c")
  .collect(Collectors.toCollection(ArrayList<String>::new));

Zauważ, że nadal możesz rozważyć pozostawienie listzmiennej wpisanej jako List<String>zamiast ArrayList<String>. Ogólny interfejs dla Listnadal wygląda dość podobnie do ArrayListimplementacji.

Same przykłady w kodzie nie wydają się dużo dodawać (oprócz więcej pisania), ale jeśli planujesz zrobić więcej, na przykład ta odpowiedź na temat konwersji ciągu znaków na listę długich , interfejs API przesyłania strumieniowego jest naprawdę potężny, ponieważ umożliwia aby potokować swoje operacje jedna po drugiej.

Ze względu na kompletność.

Racja
źródło
19
List<String> items= Stream.of(commaSeparated.split(","))
     .map(String::trim)
     .collect(toList());
Manu
źródło
1
Jedna z najlepszych odpowiedzi teraz. Listę można zmienić w tej odpowiedzi +1.
Sedrick
prace po zmianie collect(toList())nacollect(Collectors.toList()
Sundararaj Govindasamy,
W rzeczywistości collect(toList())używa statycznego importu Collectors.toList()dla zwięzłości i płynności :)
Manu
15

Nie ma do tego wbudowanej metody, ale możesz po prostu użyć w tym celu metody split ().

String commaSeparated = "item1 , item2 , item3";
ArrayList<String> items = 
new  ArrayList<String>(Arrays.asList(commaSeparated.split(",")));
Ishara
źródło
14
List<String> items = Arrays.asList(commaSeparated.split(","));

To powinno ci pomóc.

Jason Wheeler
źródło
10

możesz łączyć asList i split

Arrays.asList(CommaSeparated.split("\\s*,\\s*"))
corsiKa
źródło
8

Ten kod pomoże,

String myStr = "item1,item2,item3";
List myList = Arrays.asList(myStr.split(","));
Srinivasan.S
źródło
5

Możesz użyć Guava, aby podzielić ciąg i przekonwertować go na ArrayList. Działa to również z pustym ciągiem i zwraca pustą listę.

import com.google.common.base.Splitter;
import com.google.common.collect.Lists;

String commaSeparated = "item1 , item2 , item3";

// Split string into list, trimming each item and removing empty items
ArrayList<String> list = Lists.newArrayList(Splitter.on(',').trimResults().omitEmptyStrings().splitToList(commaSeparated));
System.out.println(list);

list.add("another item");
System.out.println(list);

wyprowadza następujące:

[item1, item2, item3]
[item1, item2, item3, another item]
Brad Parks
źródło
4

Przykład użycia Collections.

import java.util.Collections;
 ...
String commaSeparated = "item1 , item2 , item3";
ArrayList<String> items = new ArrayList<>();
Collections.addAll(items, commaSeparated.split("\\s*,\\s*"));
 ...
Filippo Lauria
źródło
1
Uniknąłeś pośredniej Arrays.asList. Niestety nadal mamy kopię z elementów tablicy do kolekcji. Miła alternatywa do zapamiętania.
YoYo
4

Istnieje wiele sposobów rozwiązania tego problemu za pomocą strumieni w Javie 8, ale IMO następujące linijki są proste:

String  commaSeparated = "item1 , item2 , item3";
List<String> result1 = Arrays.stream(commaSeparated.split(" , "))
                                             .collect(Collectors.toList());
List<String> result2 = Stream.of(commaSeparated.split(" , "))
                                             .collect(Collectors.toList());
akhil_mittal
źródło
Czy ktoś wie, jak mogę przekonwertować ten ciąg na listę oddzieloną przecinkami - ciąg s = "2017-07-12 23: 40: 00.0,153.76,16.140,60.00,, 56.00,"; List <String> splittedString = new ArrayList <String> (Arrays.asList (s.split ("\\ s *, \\ s *")));
Sunny
1
To jest nowe pytanie, nie zadawaj go jako komentarz. Utwórz nowe pytanie.
George Siggouroglou,
2

Możesz najpierw podzielić je za pomocą String.split(","), a następnie przekonwertować zwrócony ciąg arrayna za ArrayListpomocąArrays.asList(array)

Saket
źródło
2

W groovy możesz użyć metody tokenize (token znakowy):

list = str.tokenize(',')
sivareddy963
źródło
Ten mnie uratował! Dziękuję Ci.
tamerlaha,
2

Ten sam wynik można osiągnąć za pomocą klasy Splitter.

var list = Splitter.on(",").splitToList(YourStringVariable)

(napisane w kotlin)

anoopbryan2
źródło
1
Dokumentacja mówi, że ta funkcja jest beta i niestabilna.
Rubberducker
1
List commaseperated = new ArrayList();
String mylist = "item1 , item2 , item3";
mylist = Arrays.asList(myStr.trim().split(" , "));

// enter code here
deepu kumar singh
źródło
1

Zwykle używam wstępnie skompilowanego wzorca dla listy. Jest to również nieco bardziej uniwersalne, ponieważ może uwzględniać nawiasy następujące po wyrażeniach listToString.

private static final Pattern listAsString = Pattern.compile("^\\[?([^\\[\\]]*)\\]?$");

private List<String> getList(String value) {
  Matcher matcher = listAsString.matcher((String) value);
  if (matcher.matches()) {
    String[] split = matcher.group(matcher.groupCount()).split("\\s*,\\s*");
    return new ArrayList<>(Arrays.asList(split));
  }
  return Collections.emptyList();
Jan Stanicek
źródło
1

W Kotlin, jeśli twoja lista ciągów w ten sposób i możesz użyć do konwersji ciągu na ArrayList, użyj tego wiersza kodu

var str= "item1, item2, item3, item4"
var itemsList = str.split(", ")
Vijendra patidar
źródło
0
List<String> items = Arrays.asList(s.split("[,\\s]+"));
Nenad Bulatovic
źródło
0

Możesz to zrobić w następujący sposób.

To usuwa białe spacje i dzieli je przecinkami, dzięki czemu nie musisz się martwić o białe spacje.

    String myString= "A, B, C, D";

    //Remove whitespace and split by comma 
    List<String> finalString= Arrays.asList(myString.split("\\s*,\\s*"));

    System.out.println(finalString);
Dulith De Costa
źródło
-1

String -> Konwersja kolekcji : (String -> String [] -> Collection)

//         java version 8

String str = "aa,bb,cc,dd,aa,ss,bb,ee,aa,zz,dd,ff,hh";

//          Collection,
//          Set , List,
//      HashSet , ArrayList ...
// (____________________________)
// ||                          ||
// \/                          \/
Collection<String> col = new HashSet<>(Stream.of(str.split(",")).collect(Collectors.toList()));

Kolekcja -> Konwersja ciągu [] :

String[] se = col.toArray(new String[col.size()]);

Konwersja String -> String [] :

String[] strArr = str.split(",");

I Kolekcja -> Kolekcja :

List<String> list = new LinkedList<>(col);
Farzan Skt
źródło
-2

konwertuj Collection na ciąg znaków jako przecinek oddzielony w Javie 8

Obiekt listOfString zawiera elementy [„A”, „B”, „C”, „D”]

listOfString.stream().map(ele->"'"+ele+"'").collect(Collectors.joining(","))

Dane wyjściowe to: - „A”, „B”, „C”, „D”

I przekonwertuj tablicę ciągów na listę w Javie 8

    String string[] ={"A","B","C","D"};
    List<String> listOfString = Stream.of(string).collect(Collectors.toList());
Ajay Kumar
źródło
-4
ArrayList<HashMap<String, String>> mListmain = new ArrayList<HashMap<String, String>>(); 
String marray[]= mListmain.split(",");
jonsi
źródło
5
A gdzie dokładnie jest ArrayList? Czy w ogóle przeczytałeś pytanie?
Debosmit Ray
@mapeters: Było ArrayList. Wycofałem zmiany do pierwszej wersji (abyś mógł ją zobaczyć) i poprawiłem formatowanie pierwszej wersji.
dur
Pytanie dotyczy tego, jak przekonwertować ciąg znaków na ArrayList, a nie jak przekonwertować ArrayList na Array.
towarzysz