Hallo,
mir ist leider kein besserer Title eingefallen.
[edit SlaterB: war doch nicht so schwer, fachliches Thema ist markant, Art der Frage ‘Verständnis’ usw. wenig hilfreich]
Ich bin heute auf diese Methode gestoßen:
T[] items = this.items;
for (int i = 0, n = size; i < n; i++)
items** = null;
size = 0;
}```
[(aus Array aus com.badlogic.gdx.utils)](https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils/Array.java#L295)
und ich wollte fragen, welche Vorteile sie gegenüber dem hier hat (in Hinsicht auf das 'n'):
``` public void clear () {
for (int i = 0; i < size; i++)
items** = null;
size = 0;
}```
Viele Grüße und noch einen schönen Tag.
Ist doch klar: man hat mehr zu lesen. Außerdem wir so deutlicher von welchem Typ null ist…
[edit] Sorry, das n hatte ich doch glatt übersehen:
Aber diese Umleitung der Arraygröße auf eine Membervariable und dann auf n ist einfach sinnlos und ein unnötige Fehlerquelle…
Sehe auch keinen großen Vorteil von der ersten Methode. Nur macht der Autor deines Codes dies immer.
*** Edit ***
hab mir den Code mal näher angsehen finde das n aber auch nicht notwendig, vl irgend ein trick um das ganze pseudo threadsave zu bekommen. z.B. wen sich size während dem Aufruf der methode ändert.
man kann auch an Optimierung denken, size ein Attribut, jeder Zugriff darauf bisschen teurer,
aber dann hätte man die lokale Variabe n auch ‚final‘ machen sollen…
(geht in der Schleifendeklaration aber nicht? davor wäre Extra-Zeile…)
realistischer wird es wenn die Grenze Aufruf einer Methode wie size() ist, oder x/2 gerechnet werden muss usw.,
da ist die ständige Wiederholung beim Schleifendurchlauf etwas unschön,
aber letztlich meist irrelevant, wenn nicht gerade size() jedes Mal durchzählen muss
da viele Methoden n haben vielleicht auch nur aus Gewohnheit/ Code-Einheitlichkeit, wie AmunRa schon schreibt
bei
public String toString (String separator) {
if (size == 0) return "";
T[] items = this.items;
StringBuilder buffer = new StringBuilder(32);
buffer.append(items[0]);
for (int i = 1; i < size; i++) {
buffer.append(separator);
buffer.append(items**);
}
return buffer.toString();
}
Der obige Code zeigt außerdem, dass da jemand seine APIs nicht kennt: Arrays.fill(items, null); (falls size gleich Arraylänge ist, ansonsten gibt es noch eine Variante mit Bereichen)
Unter bestimmten Bedingungen könnte so ein ähnliches Pattern auch für “ein bißchen mehr Threadsicherheit” sorgen, aber … “ein bißchen mehr” bringt eigentlich nichts, deswegen kann das hier kaum ein Argument sein.
EDIT: @Landei Es kann auch sein, dass er sich an sowas wie ArrayList orientiert hat…
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
*/
public void clear() {
modCount++;
// Let gc do its work
for (int i = 0; i < size; i++)
elementData** = null;
size = 0;
}
Ist eigentlich ganz einfach… betr. Multithreading.
Wenn man in einer Methode lokale Kopien von Membern anlegt, können die Member, während die Methode noch ausgeführt wird, gefahrlos geändert werden. So kann z.B. das interne Array einer ArrayList während einem “clear()” vergrössert oder verkleinert werden. Einen kleinen Schönheitsfehler aber hätte deine “clear()”-Methode dennoch, der Member “size” müsste vor der Nullung auf 0 gesetzt werden:
T[] items = this.items;
int size = this.size;
this.size = 0;
for(int i = 0; i < size; i++) {
items** = null;
}
}```Dennoch wäre im Falle der ArrayList beim Aufruf der "add()"-Methode noch äußerste Vorsicht geboten.
Thread-sicher ist das nicht, bei add() könnte gar nicht, bei Index 0 oder bei Index size eingefügt werden, je nachdem, wo isch die Ausführung der Methode clear() zum Zeitpunkt des Aufrufs von add() gerade befindet.
Evtl. bringt Zwischenspeichern was, anstelle von immer array.length aufrufen.
Das hatte ich ja mit “ein bißchen mehr Threadsicherheit” schon angedeutet, aber … das haut ja nicht hin: Zwischen den Zeilen
T[] items = this.items;
int size = this.size;
kann ja beliebiges passieren - so dass dann ggf. mit einer falschen “size” über den lokal gespeicherten Array gelaufen wird…
size ist hinterher 0, es steht vorher aber was bei Index size, das würde der clear()-Vorgang aber vergessen und ein Element steht irgendwo im Raum. @ Marco
[QUOTE=Marco13]Das hatte ich ja mit “ein bißchen mehr Threadsicherheit” schon angedeutet, aber … das haut ja nicht hin: Zwischen den Zeilen
T[] items = this.items;
int size = this.size;
kann ja beliebiges passieren - so dass dann ggf. mit einer falschen “size” über den lokal gespeicherten Array gelaufen wird…[/QUOTE]Da ist was dran. Also doch die “length” vom lokalen Array.
vl irgend ein trick um das ganze pseudo threadsave zu bekommen
Naja, wie Spacerat gesagt hat, könnte ein anderer Thread der Elemente hinzufügt oder löscht zu nicht beabsichtigten Ergebnissen führen.
Das mit der Threadsicherheit glaube ich eigentlich nicht.
If your class is explicitly thread-safe, mention it in the Javadoc. The default assumption is that classes are not thread-safe, to reduce the amount of costly locks in the code base.
Immerhin soll der Code auf vielen Plattformen laufen und eventuell fliegen da noch viele VMs rum auf welchen das was bringt? (Android, nicht direkt GWT, roboVm)
Wie lange man sich doch mit einem N aufhalten kann. Aber vielen Dank für die Antworten
[OFFT]Ah, der Title hat sich geändert, deswegen habe ich meine Frage nicht wieder gefunden :D. Naja, Array leeren gefällt mir als Title nicht unbedingt, dass ist zwar was der Code macht, aber nicht worauf sich die Frage bezieht. afait[/OFFT]