# ArrayList in double-Array umwandeln



## Konsti (9. Jun 2009)

Hallo allerseits,

ich lese eine Datei ein mit unbekannter Anzahl an Elementen. In je einer Zeile befindet sich ein Zeitstempel plus eine Amplitude. Die beiden Werte werden in je einem ArrayList gespeichert. Da es sich um bis zu 20Mil-Werte handeln kann, habe ich gedacht, dass es sinnvoll wäre, die Daten für den Zeitstempel in ein double-Array und die Amplitude in ein float-Array umzuwandeln. Das Einlesen der Daten geht einwandfrei, jedoch scheiter es bei der Umwandlung des ArrayList zu double Array. 
Hier die grobe Vorgehensweise:

public static ArrayList<Double> temp1 = new ArrayList<Double>();
public static ArrayList <Float>temp2 = new ArrayList<Float>();
public static double[] time ; 
public static double[] amp ; 

Aufruf der methode Dateneinlesen().
Der Inhalt der Datei befindet sich in den beiden Variablen temp1 und temp2;
und nun die Umwandlung:

time=(double[]) temp1.toArray(new double[temp1.size()]);

und hier scheitert es. Der Compiler bringt folgende Fehlermeldung:

The method toArray(T[]) in the type ArrayList<Double> is not applicable for the arguments (double[])

Warum sollte es nich Anwendbar sein, diese sind doch vom gleichen Typ?
hat da eine ne Idee, wie ich dieses Problem lösen kann?
Danke im Voraus!


----------



## Der Müde Joe (9. Jun 2009)

double != Double ;-)


----------



## Marco13 (9. Jun 2009)

Womit die Frage aber nicht beantwortet ist.

```
ArrayList<Double> x = ...
float y[] = new float[x.size()];
for (int i=0; i<x.size(); i++)
{
    y[i] = (float)x.get(i);
}
```
Einfacher geht's AFAIK nicht...


----------



## Der Müde Joe (9. Jun 2009)

>ArrayList<*Double*> x = ...
>*float *y[] =

;-)


----------



## Marco13 (9. Jun 2009)

Ach, ja, das war zwar Absicht, aber da hatte ich das "_Daten für den Zeitstempel in ein double-Array und die Amplitude in ein float-Array umzuwandeln_" falsch eingeordnet - aber so viel Transferleistung sollte man wohl erwarten können


----------



## Der Müde Joe (9. Jun 2009)

Der TO hats ja auch falsch gemach 


>public static ArrayList<Double> temp1 = new ArrayList<Double>();
>public static ArrayList <*Float*>temp2 = new ArrayList<*Float*>();
>public static double[] time ;
>public static *double*[] amp ; 



> Einfacher geht's AFAIK nicht...



gleicher Meinung (ausser mit foreach)


----------



## Marco13 (9. Jun 2009)

Der Müde Joe hat gesagt.:


> (ausser mit foreach)



Zeig mal :bae:


----------



## Konsti (10. Jun 2009)

Marco 13 vielen Dank für die Idee. 
Ich möchte jedoch eine weitere Schleife aus Zeitgründen vermeiden.
Bereits das Einlesen der Datei geht etwas länger als 3 min. Eine weitere Schleife würde mein Prog. auf 6 min bringen und das ohne jegliche Berechnungen der Daten. Wenn es aber nicht anders geht, dann muss ich auf diese Methode zurückgreifen.
@ der Müde Joe: Auch dir vielen Dank für deinen Beitrag. In der Tat es sollte heißen:
public static float [] amp ;
Aber das war nur ein Tippfehler. Im Programm ist es richtig deklariert.


----------



## Der Müde Joe (10. Jun 2009)

Marco13 hat gesagt.:


> Zeig mal :bae:



Autsch...Ins eigene Fleisch geschnitten ;(

(Wollte grad das i in das Array einfügen)

Mit double != Double meinte ich das hier

```
List<Double> foo = new ArrayList<Double>();
Double[] fooArray = foo.toArray(new Double[foo.size()]); //intern ein System.arraycopy(..)
```

By the way:
Eine ArrayList benutzt intern auch ein Array. Oder besser gefragt: Was erhoffst du dir an dem array, was eine ArrayList nicht hat?


----------



## Marco13 (10. Jun 2009)

Konsti hat gesagt.:


> Ich möchte jedoch eine weitere Schleife aus Zeitgründen vermeiden.
> Bereits das Einlesen der Datei geht etwas länger als 3 min. Eine weitere Schleife würde mein Prog. auf 6 min bringen und das ohne jegliche Berechnungen der Daten.



Nur bedingt: Einlesen aus einer Datei und in eine ArrayList packen dauert u.U. DEUTLICH länger, als da dann nochmal drüberzulaufen. Wenn du eine ArrayList verwendest, gehe ich davon aus, dass du nicht weißt, wie viele Daten du am Anfang hast. Das ganze könntest du vermeiden, wenn das irgendwie vorher rausfinden könntest (oder sogar das Dateiformat so ändern könntest, dass in der ersten Zeile der Datei die Anzahl der zu lesenden Einträge steht). Dann könntest du _gleich_ einen Array der passenden Größe anlegen, und dort direkt die *d*oubles reinschreiben. (Aus der Luft gegriffene Zeitschätzung: 15 Sekunden  ). (Ein Problem bei der ArrayList ist: Sie liest 10 Elemente, und ist dann "voll", und erhöht den verfügbaren Platz auf ca. 20 Elemente, dann ca. 40 Elemente, dann ca. 80 Elemente ... die müssen bei jedem Vergrößerungsschritt umkopiert werden. Kannst auch mal testen: Wenn du weißt, das 20 Millionen Einträge kommen, die ArrayList gleich mit "new ArrayList(20000000)" erstellen - das könnte schon schneller sein. Aber die unnötigen Allokierungen für die *D*ouble-Objekte bleiben da natürlich erstmal erhalten - eine Alternative wäre DoubleArrayList (Colt 1.2.0 - API Specification) aber ... am besten wäre, direkt einen Array zu verwenden)


----------



## Landei (10. Jun 2009)

Wenn du die Liste nur immer sequentiell durchläufst und auch nur am Anfang oder Ende anfügst, wäre LinkedList die bessere Wahl.


----------



## SchonWiederFred (10. Jun 2009)

Landei hat gesagt.:


> Wenn du die Liste nur immer sequentiell durchläufst und auch nur am Anfang oder Ende anfügst, wäre LinkedList die bessere Wahl.


LinkedList verbraucht deutlich mehr Speicher als ArrayList. Bei einer ArrayList brauchst Du ein Array, in das n Referenzen reinpassen. Bei einer LinkedList hast Du dagegen n KnotenOBJEKTE, die zusätzlich noch Referenzen auf Vorgänger und Nachfolger halten. Rein von den Nutzdaten ist das schon 3x so viel Speicher, durch den Objektoverhead von Java dann sicherlich nochmal deutlich mehr.

Der sequenzielle Durchlauf kann in einer LinkedList nicht schneller sein als in einer ArrayList, da in einer ArrayList die Elemente cachefreundlich im Speicher liegen (nämlich sequenziell). Diese Garantie hast Du bei LinkedList nicht. Bei LinkedList gilt nur, dass der sequenzielle Zugriff schneller ist als der zufällige, indexbasierte AUF DERSELBEN DATENSTRUKTUR. Das wird gerne verwechselt.


----------



## Landei (10. Jun 2009)

Mag alles sein, aber wenn man die Größe vorher nicht kennt, spart man sich das Array-Umkopieren, das man bei ArrayList dann unvermeidlich hat.


----------

