Iteration von Listen

Dunas

Erfahrenes Mitglied
Hier meine Beispiel-Implementierung:

Code:
public static void main(String[] args) {
		
		HashSet<Integer> collection = new HashSet<Integer>();
	//	ArrayList<Integer> collection = new ArrayList<Integer>();
		
		for (int index = 0; index < 100000; index++) {
			collection.add(index);
		}
		
		double before = System.currentTimeMillis();
		for (int index = 0; index < 10000; index++) {
			collection.remove(new Integer(index*4));
		}
		double after = System.currentTimeMillis();
		
		System.out.println(after - before);

	}

Wenn ich das Hash-Set benutze kriege ich Zeiten von 8 - 15 mill sec, wenn ich dagegen die ArrayList verwende kriege ich Zeiten von ca. 1800 mill sec. Also die ArrayList ist um einen Faktor 200 langsamer.

ja das ist nach dem post 2 oben drüber klar. bei removen aus der array list wird ja noch alles was dahinter ist eine stelle nach vorne geschoben.


Ja, das verstehst du richtig. Mein Code sieht wie folgt aus:

Code:
for(int i = 0; i < m; i++) {
      System.gc();
     //population enthaelt als Klassenvarivable die Collection
     Population population = new Population();
     for (int j = 0; j < n; j++) {
          //in diesem Schritt werden Objekte an die Collection angehaengt bzw. geloescht
          poplation.simulateNextTimeStep();
      }
      //hier wird noch in eine Datei geschrieben (BufferedWriter, flush() wird gerufen)
}

hier kann ich jetzt nichts wildes entdecken.
vieleicht solltest du nacher alle variablen mal auf null setzen. und nachdem du System.gc() aufrufst nen sleep von 1 sekunde einbaust. dann hat der gb etwas zeit.
// edit: ok wird wohl nicht viel bringen den threat ne sekunde schlafen zu lassen. aber versuchen kannst du es ja mal.
 
Zuletzt bearbeitet:
S

Sebastian G

Das System.gc() sagt nicht explizit aus, dass der GC sofort alle alten Referenzen frei gibt. Viel mehr wird dem GC mitgeteilt, seine GC Anstrengen zu erhöhen. Aber genau bin ich da auch noch nicht schlau draus geworden.

http://java.sun.com/javase/6/docs/api/java/lang/System.html#gc()

Beim HashSet muss dir klar sein, dass der Hash-Wert deines Objektes als Key verwendet wird. Und das dieser Key eindeutig ist in deinem Set. Daher überschreibst du die Werte, wenn der Hash Wert gleich ist.

Der Hash-Wert wird durch die hashCode Methode des Objektes erzeugt. Wenn das Objekt keine hashCode Methode hat (wird die von Object verwendet), wird die SpeicherAdresse der Instanz als Hash Wert verwendet.


Wenn mein Objekt keine eigene hashCode Methode hat, wird die Speicheradresse der Instanz verwendet. D.h. also wenn ich die Objekte nacheinander inintialisiere und dann dem HashSet hinzufuege, sind alle drin (keiner wird ueberschrieben). Nur wenn ich eine Instanz doppelt hinzufuege wird sie ueberschrieben. Hab ich das richtig verstanden? Also selbst wenn der Inhalt der Instanzen identisch ist, ist der HashCode (auf Grund der unterschiedlichen Speicheradresse der Instanzen) verschieden.



Das Problem mit dem Speicherplatz (Einzeldurchlauf vs. for-Loop) hat sich geloest. Hat an einem anderen Programmteil gelegen. Sorry.


Gruss
Sebastian
 

Anime-Otaku

Erfahrenes Mitglied
Wenn mein Objekt keine eigene hashCode Methode hat, wird die Speicheradresse der Instanz verwendet. D.h. also wenn ich die Objekte nacheinander inintialisiere und dann dem HashSet hinzufuege, sind alle drin (keiner wird ueberschrieben). Nur wenn ich eine Instanz doppelt hinzufuege wird sie ueberschrieben. Hab ich das richtig verstanden? Also selbst wenn der Inhalt der Instanzen identisch ist, ist der HashCode (auf Grund der unterschiedlichen Speicheradresse der Instanzen) verschieden.
Gruss
Sebastian

Ja hast du, weil dann die hashcode Methode von Object verwendet wird.