ERLEDIGT
NEIN
NEIN
ANTWORTEN
8
8
ZUGRIFFE
1601
1601
EMPFEHLEN
-
Hallo,
Ich habe folgende GUI:
Der Benutzer gibt verschiedene Strings ein in eine editierbare JCombobox. Danach drückt er rechts davon den add Button damit der string der JCB geaddet wird. Der Benutzer kann auch in der Liste mit dem delete Button einen Eintrag löschen. Doch das alle ist nebensächlich... Wichtiger ist, dass beim drücken des Save Buttons ALLE String-Elemente in der JComboBox in einer xml datei gespeichert werden in einer List<String>.
Wenn aber jedesmal alle Strings die sich in der JCB befinden in die xml Datei geschrieben werden. Bekomme ich ja jedesmal redundante Elemente in der xml Datei so:
Inhalt der JCB:
String1
String2
String3
Inhalt der xml datei:
String1
String2
String3
String1
String2
String3
String1
String2
String3
Nun frage ich micht wie ich verhindern kann das jedesmal ALLE Strings aus der JCBox in der xml gespeichert werden...
1.) Gibt es eine jaxb Annotation z.B. die besagt ein Element in einer Liste darf nur einmal vorkommen?
oder
2.)Bevor ich jeden String in der JCB der xml Datei hinzufüge prüfe ich ob der String in der xml schon vorhanden ist. Bei 10 strings in der JCB und existieren 10 strings in der xml datei ergibt das 100 IF prüfungen was net so performant sein dürfte...
Weiß jemand hier eine vernüftige Lösung ?
-
Nun die Lösung ist ganz einfach: Nimm ein Set und keine List. In einem Set kann jedes Element nur einmal vorhanden sein.
Die JAXB Annotationen kannst du so weiter verwenden.
-
ganz so einfach ists auch net
und anstatt List liste = new ArrayList() musst ich ne = new HashSet() nehmen und weiteres Problem ergibt sich dadurch:
Code :1 2 3 4
for(int i = 0 ; i < settingsData.getSetMovieFormat().size() ; i++) { getMovieFormatCB().addItem(settingsData.getSetMovieFormat().get(i)); }
Das HashSet/Set kennt keine get(i); methode, wie lese ich nun die Strings einzeln aus dem Set aus und einzeln in die JComboBox genannt movieFormatCB ? Es gibts zwar eine addAll() methode für die Set doch eine AddAllitem gibts für die JCBox leider nicht.
Wie könnt ich da jetzt am geschicktesten vorgehen?Geändert von will2k (18.05.08 um 15:09 Uhr)
-
Man sollte über Listen sowieso nicht mit einer normalen for-Schleife zugreifen. Das ist einfach zu langsam.
Besser ist es einen Iterator zu nehmen:
Code java:
Oder noch einfacher ab Java 1.5:
Code java:
Achso noch besser wäre für dich wohl ein TreeSet<String> denn dann sind die Elemente sogar alphabetisch sortiert, was immer ganz gut ist in soner Combobox.
-
Code :
1 2 3 4 5
SettingsData settingsData = new SettingsData(); JAXBContext jc = JAXBContext.newInstance(SettingsData.class); Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); OutputStream os = new FileOutputStream( "test.xml" );
Code :1 2 3 4
for(String element : this.getMovieFormatCB().toString()) { settingsData.getSetMovieFormat().add(element); }
das hier ist code aus der saveXML-Methode. Ich will ja alle strings aus der JCombobox auslesen element für element, doch this.getMovieFormatCB() mag java nicht... alle Strings aus der JCB in ein String-Array lesen und dieses Array mit for zu durchlaufen element für element kanns ja net sein oder?
Code :1
m.marshal(settingsData, os);
Fehler bei this.getMovieFormatCB().toString() -->
Code :1
Can only iterate over an array or an instance of java.lang.Iterable
-
Also nochmal zum Verständnis:
for(String element : list)
Liest sich als: Für alle String element in list
Bei der Combobox müßte es heißen:
Code java:
Hast du noch Probleme damit die API zu verwenden?
Ich würde dir außerdem statt:
settingsData.getSetMovieFormat().add(element);
empfehlen in settingsData direkt eine Methode addMovieFormat vorzustehen. Ist ein wenig schöner.
Besonders weil man in einem get eigentlich keine Modifizierbare Liste/Set zurückgeben sollte:
Code java:1 2 3
public Set getMovieFormats(){ return Collections.unmodifiableSet(movieFormats); }
Das verhindert daß versehentlich Elemente einfach so hinzugefügt werden können.
-
@zeja
Wie sollte man denn auf eine Liste zugreifen? Der Iterator ist langsamer als mit einer normalen for-Schleife.
Die performanteste Lösung die ich kenne um über eine Liste zu iterieren ist diese
Man sollte auch die Größe der Liste einer Variablen zuordnen, wie hier im Beispiel und nichtCode :1 2 3
for(int i=0, size = list.size(); i<size; i++){ }da so bei jedem Schleifendurchlauf die Listengröße neu abgefragt wird.Code :1
for(int i=0; i<list.size(); i++)
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListIterationPerformance { /** * @param args */ public static void main(String[] args) { List<String> list1 = new ArrayList<String>(); fillList(list1); long start, stop; start = System.currentTimeMillis(); for(String s : list1){ } stop = System.currentTimeMillis(); System.out.println(stop-start); start = System.currentTimeMillis(); for(Iterator<String> it = list1.iterator(); it.hasNext();){ it.next(); } stop = System.currentTimeMillis(); System.out.println(stop-start); start = System.currentTimeMillis(); for(int i = 0, size = list1.size(); i<size; i++){ list1.get(i); } stop = System.currentTimeMillis(); System.out.println(stop-start); } private static void fillList(List<String> list){ for(int i = 0; i < 1000000; i++){ list.add("test"+i); } } }
Bei einem Set kann man natürlich nur mit einem Iterator auf eine Liste zugreifen. Wobei man die altmodische Variante nehmen sollte und nicht die seit Java 1.5.78
62
16
MFG
SaschaEs ist schwer Allwissend zu sein. Aber ich komme damit klar. ;-)
-
Achja das war wieder die Sache die in Java keinen Sinn macht: Ein Iterator ist langsamer als ein direkter Zugriff. Für mich sollte nen Iterator immer den schnellsten Zugriff bieten...
Aber einen Fehler hast du gemacht in deinem Performance-Test: Der Iterator ist nur schneller als das for-each weil du die Zuweisung an einen String herausgelassen hast, der ja im for-each gemacht wird.
Korrekter ist es also so:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
package de.tutorials; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListIterationPerformance { public static void main(String[] args) { List<String> list1 = new ArrayList<String>(); fillList(list1); long start, stop; start = System.currentTimeMillis(); forEachLoop(list1); stop = System.currentTimeMillis(); System.out.println("For each:\t" + (stop - start)); start = System.currentTimeMillis(); forIteratorLoop(list1); stop = System.currentTimeMillis(); System.out.println("For iterator:\t" + (stop - start)); start = System.currentTimeMillis(); forSizeLoop(list1); stop = System.currentTimeMillis(); System.out.println("For size:\t" + (stop - start)); } private static void forSizeLoop(List<String> list1) { for (int i = 0, size = list1.size(); i < size; i++) { String s = list1.get(i); } } private static void forIteratorLoop(List<String> list1) { for (Iterator<String> it = list1.iterator(); it.hasNext();) { String s = it.next(); } } private static void forEachLoop(List<String> list1) { for (String s : list1) { } } private static void fillList(List<String> list) { for (int i = 0; i < 1000000; i++) { list.add(Integer.toString(i)); } } }
Schaut man ins class-File:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Method descriptor #22 (Ljava/util/List;)V // Signature: (Ljava/util/List<Ljava/lang/String;>;)V // Stack: 1, Locals: 3 private static void forIteratorLoop(java.util.List list1); 0 aload_0[list1] 1 invokeinterface java.util.List.iterator() : java.util.Iterator [74] [nargs: 1] 6 astore_1 [it] 7 goto 20 10 aload_1 [it] 11 invokeinterface java.util.Iterator.next() : java.lang.Object [78] [nargs: 1] 16 checkcast java.lang.String [69] 19 astore_2 20 aload_1 [it] 21 invokeinterface java.util.Iterator.hasNext() : boolean [84] [nargs: 1] 26 ifne 10 29 return
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Method descriptor #22 (Ljava/util/List;)V // Signature: (Ljava/util/List<Ljava/lang/String;>;)V // Stack: 1, Locals: 3 private static void forEachLoop(java.util.List list1); 0 aload_0[list1] 1 invokeinterface java.util.List.iterator() : java.util.Iterator [74] [nargs: 1] 6 astore_2 7 goto 20 10 aload_2 11 invokeinterface java.util.Iterator.next() : java.lang.Object [78] [nargs: 1] 16 checkcast java.lang.String [69] 19 astore_1 20 aload_2 21 invokeinterface java.util.Iterator.hasNext() : boolean [84] [nargs: 1] 26 ifne 10 29 return
Sieht man dass der generierte Teil für for-each und for-iterator nun auch (nahezu) gleich sind, so wie es sein sollte.
Ausgabe:
Code :1 2 3
For each: 55 For iterator: 55 For size: 19
So kann man auch schön erkennen warum man keinen Vector nehmen sollte wenn man diesen nicht benötigt:
Code :1 2 3
For each: 143 For iterator: 144 For size: 72
also ein gaaanzes Stück langsamer.
-
Also bei mir sind die Zeiten gleich geblieben.
Aber das ist ja erstmal egal. Ich wollte nur deutlich machen, dass die Methode ohne Iterator immer noch die schnellste ist.
MFG
Sascha
EDIT:
Dass intern ein Iterator verwendet wird, weiß ich. Nach nochmal mehrmaligem ausführen, muss ich sagen, dass sich der Iterator schon der for-each-Schleife genähert hat. Aber ich hab ja schon erwähnt worauf ich hinaus wollte.
Es ist schwer Allwissend zu sein. Aber ich komme damit klar. ;-)
Ähnliche Themen
-
Reflection - Wie kann ich Werte zu einer List<> hinzufügen?
Von Jacky87 im Forum .NET WPF & SilverlightAntworten: 2Letzter Beitrag: 18.05.10, 18:24 -
Einer Zip Datei ein leeres Verz. hinzufügen
Von DarthShader im Forum JavaAntworten: 8Letzter Beitrag: 24.09.09, 11:31 -
Probleme mit entfernen von einer Datei
Von Eddymaniac im Forum Linux & UnixAntworten: 2Letzter Beitrag: 01.10.06, 20:17 -
allen feldern einer spalte einen string hinzufügen
Von megatom im Forum Relationale DatenbanksystemeAntworten: 2Letzter Beitrag: 23.06.05, 13:07 -
[PHP / XLS] Zeilenumbrüche in einer XLS Datei entfernen
Von micha im Forum PHPAntworten: 0Letzter Beitrag: 23.03.04, 11:35





Zitieren



Login





