Od Arraylist do Array

111

Chcę wiedzieć, czy konwersja z ArrayList do Array jest bezpieczna / wskazana? Mam plik tekstowy, w którym każda linia zawiera ciąg:

1236
1233
4566
4568
....

Chcę je przeczytać do listy tablic, a następnie przekonwertować ją na Array. Czy jest to wskazane / zgodne z prawem?

dzięki

Eddy Freeman
źródło
8
Państwo może , ale nie dały nam prawie wystarczająco dużo informacji, aby stwierdzić, czy jest to dobry pomysł, czy nie.
Jon Skeet
6
ArrayLists są w porządku. Jedynym powodem, dla którego widzę konwersję na Array, jest to, że musisz wywołać metodę, która tego wymaga.
mike jones

Odpowiedzi:

214

Tak , konwersja pliku ArrayListdo formatuArray . To, czy jest to dobry pomysł, zależy od zamierzonego zastosowania. Czy potrzebujesz operacji, które ArrayListzapewnia? Jeśli tak, zachowaj plik ArrayList. W przeciwnym razie konwertuj!

ArrayList<Integer> foo = new ArrayList<Integer>();
foo.add(1);
foo.add(1);
foo.add(2);
foo.add(3);
foo.add(5);
Integer[] bar = foo.toArray(new Integer[foo.size()]);
System.out.println("bar.length = " + bar.length);

wyjścia

bar.length = 5
ObscureRobot
źródło
Co się stanie, jeśli ArrayList jest pusty?
ThanosFisherman
48
Wtedy jest pusty.
IMustBeSomeone
1
The method toArray(T[]) in the type ArrayList<Character> is not applicable for the arguments (char[])
Aaron Franke
75

To najlepszy sposób (IMHO).

List<String> myArrayList = new ArrayList<String>();
//.....
String[] myArray = myArrayList.toArray(new String[myArrayList.size()]);

Ten kod działa również:

String[] myArray = myArrayList.toArray(new String[0]);

Ale to mniej efektywne: tablica ciągów jest tworzona dwukrotnie: za pierwszym razem tworzona jest tablica o zerowej długości, a następnie tworzona jest tablica o rzeczywistym rozmiarze, wypełniana i zwracana. Jeśli więc znasz wymagany rozmiar (od list.size()), powinieneś stworzyć tablicę, która będzie wystarczająco duża, aby umieścić wszystkie elementy. W takim przypadku nie jest przydzielane ponownie.

AlexR
źródło
4
dobre wyjaśnienie różnicy między new String[0]inew String[size]
gamliela
4
new String[0]jest faktycznie bardziej wydajna. shipilev.net/blog/2016/arrays-wisdom-ancients
Radiodef
5
ArrayList<String> myArrayList = new ArrayList<String>();
...
String[] myArray = myArrayList.toArray(new String[0]);

To, czy jest to „dobry pomysł”, naprawdę zależy od twojego przypadku użycia.

Brian Roach
źródło
dzięki, tylko ciekawy wiedzieć: nie muszę deklarować rozmiaru tablicy?
Eddy Freeman
JavaDocs to Twój przyjaciel. Jeśli przekazywana tablica jest zbyt mała, zwracana jest nowa tablica. Druga wersja metody, która nie przyjmuje argumentów, zwraca tablicęObject
Brian Roach
3

zakładając, że v jest ArrayList:

String[] x = (String[]) v.toArray(new String[0]);
Erhan Bagdemir
źródło
1

Istnieją dwa style konwersji kolekcji na tablicę: albo przy użyciu tablicy o ustalonym rozmiarze (jak c.toArray(new String[c.size()])), albo przy użyciu pustej tablicy (jak c.toArray(new String[0])). W starszych wersjach Javy zalecane było używanie tablic o wstępnie ustalonym rozmiarze, ponieważ wywołanie odbicia, które jest niezbędne do utworzenia tablicy o odpowiednim rozmiarze, było dość powolne. Jednak od późnych aktualizacji OpenJDK 6 wywołanie to było zintensyfikowane, sprawiając, że wydajność wersji z pustą tablicą była taka sama, a czasami nawet lepsza w porównaniu z wersją o wcześniejszym rozmiarze. Również przekazywanie tablicy o wstępnie ustalonym rozmiarze jest niebezpieczne dla zbierania współbieżnego lub synchronizowanego, ponieważ wyścig danych jest możliwy między rozmiarem a wywołaniem toArray, co może skutkować dodatkowymi wartościami zerowymi na końcu tablicy, jeśli kolekcja została jednocześnie skurczona podczas operacji. Możesz śledzić jednolity styl:albo przy użyciu pustej tablicy (co jest zalecane we współczesnej Javie), albo przy użyciu tablicy o ustalonej wielkości (która może być szybsza w starszych wersjach Javy lub maszynach JVM innych niż HotSpot) .

Alexander Savin
źródło
1

To jest zalecane użycie dla nowszej wersji Java (> Java 6)

String[] myArray = myArrayList.toArray(new String[0]);

W starszych wersjach Javy zalecane było używanie tablic o wstępnie ustalonym rozmiarze, ponieważ wywołanie odbicia, które jest niezbędne do utworzenia tablicy o odpowiednim rozmiarze, było dość powolne. Jednak od późnych aktualizacji OpenJDK 6 wywołanie to było zintensyfikowane, sprawiając, że wydajność wersji z pustą tablicą była taka sama, a czasami nawet lepsza w porównaniu z wersją o wcześniejszym rozmiarze. Również przekazywanie tablicy o wstępnie ustalonym rozmiarze jest niebezpieczne dla zbierania współbieżnego lub zsynchronizowanego, ponieważ wyścig danych jest możliwy między rozmiarem a wywołaniem toArray, co może skutkować dodatkowymi wartościami zerowymi na końcu tablicy, jeśli kolekcja została jednocześnie zmniejszona podczas operacji. Ta inspekcja pozwala na przestrzeganie jednolitego stylu: albo użycie pustej tablicy (co jest zalecane we współczesnej Javie), albo użycie tablicy o ustalonym rozmiarze (co może być szybsze w starszych wersjach Javy lub maszynach JVM nie opartych na HotSpot).

majurageerthan
źródło
0

Interfejs Collection zawiera metodę toArray () służącą do konwersji nowej kolekcji na tablicę. Istnieją dwie formy tej metody. Wersja bez argumentów zwróci elementy kolekcji w tablicy Object: public Object [] toArray (). Zwrócona tablica nie może rzutować na żaden inny typ danych. To jest najprostsza wersja. Druga wersja wymaga podania typu danych tablicy, którą chcesz zwrócić: public Object [] toArray (Object type []).

 public static void main(String[] args) {  
           List<String> l=new ArrayList<String>();  
           l.add("A");  
           l.add("B");  
           l.add("C");  
           Object arr[]=l.toArray();  
           for(Object a:arr)  
           {  
                String str=(String)a;  
                System.out.println(str);  
           }  
      }  

w celach informacyjnych zapoznaj się z tym linkiem http://techno-terminal.blogspot.in/2015/11/how-to-obtain-array-from-arraylist.html

satynowy
źródło
0

Jednym podejściem byłoby dodanie Second for Loop, gdzie drukowanie odbywa się wewnątrz pierwszej pętli for. Lubię to:

static String[] SENTENCE; 

public static void main(String []args) throws Exception{

   Scanner sentence = new Scanner(new File("assets/blah.txt"));
   ArrayList<String> sentenceList = new ArrayList<String>();

   while (sentence.hasNextLine())
   {
       sentenceList.add(sentence.nextLine());
   }

   sentence.close();

   String[] sentenceArray = sentenceList.toArray(new String[sentenceList.size()]);
  // System.out.println(sentenceArray.length);
   for (int r=0;r<sentenceArray.length;r++)
   {
       SENTENCE = sentenceArray[r].split("(?<=[.!?])\\s*"); //split sentences and store in array 

       for (int i=0;i<SENTENCE.length;i++)
       {
           System.out.println("Sentence " + (i+1) + ": " + SENTENCE[i]);
       }
   }    

}
Vipin Menon
źródło
0
ArrayList<String> a = new ArrayList<String>();
a.add( "test" );
@SuppressWarnings( "unused")
Object[] array = a.toArray();

Zależy to od tego, co chcesz osiągnąć, jeśli później będziesz musiał manipulować tablicą, kosztowałoby to więcej wysiłku niż utrzymanie ciągu w ArrayList. Masz również losowy dostęp z ArrayList autorstwalist.get( index );

sztaplarka
źródło