Geht es auch schneller doppelte Einträge zu löschen?

Status
Nicht offen für weitere Antworten.

Der Programmierer

Aktives Mitglied
Hi leutz,

ich hab ein Programm, welches doppelte Einträge einer Liste findet und dann einen Eintrag der beiden löscht, das sieht wie folgt aus:

Code:
			for(int i = 0; i<liste.size(); i++)
			{
				String test = liste.get(i);
				for(int x = i+1; x<liste.size(); x++)
				{
					String lol = liste.get(x);
					if(lol.equals(test))
					{
						liste.remove(x);
					}
					fortschritt=fortschritt+0.5;
					bar.setValue((int)fortschritt);

				}
			}

Allerdings ist das bei der Menge die ich habe (>40.000) sehr langsam. Gibt es da ne performantere Lösung?
Jemand hat mal gesagt das könnte man auch mit nem collections machen, aber ist das wirklich performanter?
 
S

SlaterB

Gast
wenn du deins als langsam empfindest, dann empfinde doch mal wie schnell das andere ist?
sprich: im 40.000er-Alltag benutzen oder direkt testen und Zeit messen
(System.currentTimeInMillies())

mit Map/ Set sollte das sehr viel schneller sein, ja,
bei dir werden ~ 40.000 * 40.000 Vergleiche durchgeführt,

es reichen aber 40.000, jedes Element nur einmal vergleichen,
und zwar indem man die Elemente nicht blind in einer Liste speichert sondern an einem speziell sortierten Platz

List ohneDoppelte = new ArrayList(new HashSet(alteListe));
oder ähnlich
---------

ein anschaulicheres Verfahren, auch recht gut:
die Liste sortieren (geht mit guten Algorithmen wie Collections.sort() auch deutlich schneller als 40.000 * 40.000)
und nur benachbarte Elemente vergleichen
 

Wildcard

Top Contributor
Zuerst mal die Frage ob du wirklich eine Liste brauchst und nicht einfach ein Set nehmen kannst, dann kannst du dir das ganze sparen.
 

Youlian

Mitglied
Ich schließe mich meinem Vorredner an und möchte dich auch noch darauf hinweisen:
Falls "bar" eine grafische Komponente wie JProgressBar ist, würde ich die nicht bei jedem Durchlauf setzen.

Am schönsten wäre natürlich ein eigener Thread/Timer der alle paar 100ms den Fortschritt setzt. So bekommst du einen schönen, flüssigen Balken. :)
 

Der Programmierer

Aktives Mitglied
Edit: dieser BEitrag hat sich erledigt ich war nur zu langsam und hab die anderen posts nicht mehr mitgekriegt.

Es muss nicht unbedingt ne Liste sein. Eigentlich muss ich Zeilen in nem Textdokument die doppelten Einträge löschen.
Aber mir ist nix besseres als ne Liste eingefallen!
 

Der Programmierer

Aktives Mitglied
Ich glaub ich steh aufem Schlauch. Seit wann löscht HashSet alle doppelte Einträge?

Seid mir nicht böse wenn ich mich gerade etwas sehr blöd anstelle!
 

Wildcard

Top Contributor
HashSet#add hat gesagt.:
Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.
 

Der Programmierer

Aktives Mitglied
oder anscheinend doch nicht ^^
Irgendwie sind meine Dateien jetzt ganz leer!

Code:
			lnr = new LineNumberReader(new FileReader(dateiname));


			for(int i = 0 ; i<zeilen; i++)
			{
				zwischen = lnr.readLine();
				liste.add(zwischen);
				fortschritt = fortschritt + 0.5;
				bar.setValue((int)fortschritt);
			}


			BufferedWriter buffy = new BufferedWriter(new FileWriter(dateiname));
			for(int i = 0; tmp.hasNext(); i++)
			{
				it = tmp.next();
				buffy.write(it);
				buffy.newLine();
				fortschritt=fortschritt+0.5;
				bar.setValue((int)fortschritt);
			}

			buffy.close();

Hat das einen bestimmten Grund oder will Sun mich nur ärgern?

Schonmal danke für eure Hilfe
Der Programmierer
 

Der Programmierer

Aktives Mitglied
oh entschuldigung hab ganz vergessen den Abschnitt mit den ganzen definitionen zu posten!

Code:
	LineNumberReader lnr;
	HashSet<String> liste = new HashSet<String>();	
	Iterator <String> tmp = liste.iterator();
	int zeilen;
	BufferedReader zaehler;
	String         zwischen;
	String dateiname       ;
	JProgressBar bar;
	double fortschritt = 0;
	String it;
	

//Konstruktor etc...

	public void run()
	{               


		
		System.out.println("BEI DER ARBEIT");

		try
		{
			
			lnr = new LineNumberReader(new FileReader(dateiname));


			for(int i = 0 ; i<zeilen; i++)
			{
				zwischen = lnr.readLine();
				liste.add(zwischen);
				fortschritt = fortschritt + 0.5;
				bar.setValue((int)fortschritt);
			}


			BufferedWriter buffy = new BufferedWriter(new FileWriter(dateiname));
			for(int i = 0; tmp.hasNext(); i++)
			{
				it = tmp.next();
				buffy.write(it);
				buffy.newLine();
				fortschritt=fortschritt+0.5;
				bar.setValue((int)fortschritt);
			}

			buffy.close();
			setVisible(false);
 

Wildcard

Top Contributor
Den Iterator darfst du erst dann erzeugen lassen wenn das set gefüllt ist.
Ein leerer Iterator macht wenig Sinn.
 

Der Programmierer

Aktives Mitglied
Boah seiht ihr göttlich!

Das rennt wie blöd. Ich habs gerade mit 2.000.000 Einträgen probiert und es ging in unter 7 Sekunden!

Vielen dank!!!!!!!
 
S

SlaterB

Gast
das HashSet nenn mal set bzw. menge statt liste ;)
aber über Variablennamen wie zwischen und tmp kann man ja auch streiten..
 
R

ray3002

Gast
Hmmm... bin gerade auf den Thread gestossen, weil ich ein ganz ähnliches Problem habe. Ich will in irgendeiner Collection die Duplikate rausfiltern, ABER ich brauche die Häufigkeit der doppelt vorkommenden Elemente. Ich habe mal mit Collections.sort() die ganze Sache sortiert und gehe sie dann nach aufeinenander folgenden gleichen Elementen durch. Habe es mit einer LinkedList und mit einem Stack probiert, aber irgendwie wollen die ca. 220.000 Strings da nicht schnell durch. Gibt es da nicht irgendwie was bessers?
Hier mal meine Ansätze:


Mit Stack:
Code:
	public Stack<String> duplikateAussortieren(Stack<String> stack) {
		Collections.sort(stack);
		String string1;
		String string2;
		int size = stack.size();
		Stack<String> neuerStack = new Stack<String>();
		monitor.setMaximum(size);
		monitor.init();
		

		while (stack.size() > 2) {
			string1 = stack.pop();
			neuerStack.add(string1);
			string2 = stack.pop();
			monitor.setValue(size - stack.size() + (size / 100));

			if (string1.equals(string2)) {
				while (string1.equals(string2)) {
					monitor.setValue(size - stack.size() + (size / 100));
					if(stack.size() > 1)
					string2 = stack.pop();
					

				}

			} else {
				neuerStack.add(string2);
			}
		}
		monitor.clear();
		return neuerStack;

	}

Monitor kann man ignorieren, ist ein Statusbalken.

Und hier noch meine LinkedList Lösung:

Code:
	public LinkedList<String> findDuplicates(LinkedList<String> list) {
	
		for (Iterator<String> i = list.iterator(); i.hasNext();) {
		
			String s = i.next();
			if (s.equals(i.next())) {
				i.remove();
			}
		}
	
		return list;
	}

Ich programmiere noch nicht so lange, wie man sicher sehen kann ;-). Wäre aber trotzdem sehr nett, wenn mir jemand auf die Sprünge helfen könnte.

Grüße aus Kölle

Ray

[/code][/quote]
 
S

SlaterB

Gast
was genau ist denn die Frage?
dauert irgendwas davon mehr als 100 ms?
wieviele doppelte unter diesen 220.000, wie lang sind die Strings durchschnittlich?

wolltest du nicht noch die Anzahl pro Doppelten zählen?

-------


wahrscheinlich ist das Sortieren mit Abstand der größte Teil der Arbeit,
wenn du einfach nur Doppelte filtern willst, dann könntest du alle Elemente einmal in ein HashSet schreiben (und evtl. wieder in eine Liste zurück)

oder die Hauptliste unsortiert durchlaufen, Elementen nebenbei mit einem HashSet abgleichen,
(einfügen, schauen ob Set größer geworden ist oder contains() )


wenn die Liste schon sortiert vorliegt, dann gehts kaum schneller

------

edit: ach je, darum gings am Anfang des Topics ja auch schon,
man sieht, dass ich immer das gleiche wiederhole ;)

List ohneDoppelte = new ArrayList(new HashSet(alteListe));
oder ähnlich
 

byte

Top Contributor
Brauchst Du am Ende für jedes mehrfach vorkommende Element genau die Anzahl an Vorkommen? Dann könntest Du folgendes machen:

(ungetestet)
Code:
List<String> stringList ...;
Set<String> stringSet = new HashSet<String>(stringList.size());
// Mapping zwischen String und Häufigkeit
Map<String, Integer> frequency = new HashMap<String, Integer>(stringList.size());

for (String s : strings) {
  if (!stringSet.add(s)) {
    // Eintrag in Map hochzählen
  }
}

Da HashSet#add und HashMap#get/put konstante Laufzeit haben, sollte das Ganze auf ne Laufzeit von n hinauslaufen.
 
S

SlaterB

Gast
wobei die Map selber auch als Set gelten könnte

for (String) {
Integer oldCount = map.get
newCount = 1 oder oldCount+1
map.put
}

map.keySet();
ist am Ende das Set an Strings ohne Doppelte
 
R

ray3002

Gast
Ahhh das sieht nach einer praktikablen Möglickeit aus, werde es gleich mal ausprobieren.
Vielen Dank! Ray
 
G

Gast

Gast
@der Programmierer, dein Code vom Anfang 1. Post, hat einen Bug, Bei einer Liste oder was auch immer. Die so gestrickt ist, das es einmal zu einer Konstellation wie dieser kommt.

{bereits fertig sortiert}, element a, element a, element a

so terminiert der Algorithmus mit folgendem Ergebnis

{bereits fertig sortiert}, element a, element a.


Code:
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Vector;

public class TestSortierung {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Vector<String> vector = new Vector<String>();
		for (int i = 0; i < 3; i++) {
			vector.add("String1");
			vector.add("String2");
			vector.add("String3");
			vector.add("String4");
			vector.add("String5");
		}
		printCollection(vector);
		Vector<String> clone = (Vector) vector.clone();
		long start = System.currentTimeMillis();
		for (int i = 0; i < vector.size(); i++) {
			String test = vector.get(i);
			for (int x = i + 1; x < vector.size(); x++) {
				String lol = vector.get(x);
				if (lol.equals(test)) {
					vector.remove(x);
				}

			}
		}
		System.out.println(System.currentTimeMillis() - start);
		printCollection(vector);
		
		printCollection(clone);
		start = System.currentTimeMillis();
		HashSet<String> set = new HashSet<String>();
		for (String str : clone) {
			set.add(str);
		}
		System.out.println(System.currentTimeMillis()-start);
		printCollection(set);
	}

	private static void printCollection(Collection<String> collection) {
		
		for(String str : collection){
			System.out.println(str);
		}
		System.out.println();
	}

}

Fals es jemand ausprobieren möchte
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Erste Schritte Aufgabe - Geht das auch schneller ? Allgemeine Java-Themen 7
S Mit Methoden kann man definieren für was <T> steht. Geht das auch irgendwie für Variablen? Allgemeine Java-Themen 12
F 2 JsonArray vergleichen, geht es auch einfacher ? Allgemeine Java-Themen 3
X Datentypen Byte geht nicht höher als 126 auch nicht mit casten? Allgemeine Java-Themen 22
C Methodenkopf: Zu was wenns auch ohne geht? Allgemeine Java-Themen 3
Chris_1980 Geht das nicht auch einfacher (Arcanoid Multiball) Allgemeine Java-Themen 2
G Warum einfach wenns kompliziert auch geht? Allgemeine Java-Themen 12
HolyFUT Best Practice Wie geht man mit "schlechten" Projekten um? Allgemeine Java-Themen 7
LimDul Hä? Lambda-Ausdruck geht, Methoden-Referenz nicht Allgemeine Java-Themen 8
LimDul Direktes return eines Array geht nicht Allgemeine Java-Themen 20
M Test geht auf Travis und mit Github Action schief aber nicht lokal Allgemeine Java-Themen 3
M Console geht nicht auf (Windows 10) Allgemeine Java-Themen 3
W Enumeration ein Array/List als Eigenschaft mitgeben - warum geht das nicht? Allgemeine Java-Themen 0
P Erste Schritte HauptFrame geht nicht Allgemeine Java-Themen 7
L Applet Applet zu JavaWebStart migrieren - simples sample geht nicht Allgemeine Java-Themen 2
KeVoZ_ Java Mail senden - geht nicht Allgemeine Java-Themen 4
K API - Wie geht das? Allgemeine Java-Themen 2
D Klassenübergreifender Befehl geht nicht Allgemeine Java-Themen 10
J Umwandeln von URL zu File und danach kopieren geht nicht Allgemeine Java-Themen 1
M JUnit Serverseitig? Wie geht sowas? Allgemeine Java-Themen 2
E JavaFX String-Wert geht "verloren" - ratlos Allgemeine Java-Themen 2
B Fehler beim Auslesen von Einstellungen. Zwei ähnliche Blöcke, nur eins geht. Allgemeine Java-Themen 5
H Unicode ausgeben ohne Umwandlung - geht das? Allgemeine Java-Themen 3
F Java Anwendung Remote starten geht nicht Allgemeine Java-Themen 0
M Eingabe von Arrays geht über gewünschte Anzahl hinaus Allgemeine Java-Themen 2
K print() geht nicht ohne println() Allgemeine Java-Themen 3
V 2D-Grafik BufferdImage aus gif Datei in Jar erzeugen geht nicht. Allgemeine Java-Themen 6
Fl4sh1 Autovervollständigungfenster geht nicht (eclipse) Allgemeine Java-Themen 10
P Absatz im String / Excel / /n geht nicht Allgemeine Java-Themen 2
Z Java geht nicht im Browser Allgemeine Java-Themen 5
J Laden von JAR Files geht ohne ADMIN Rechte sehr langsam Allgemeine Java-Themen 6
B Keylistener geht nicht Allgemeine Java-Themen 9
R Wie geht man mit CachedRowSet um Allgemeine Java-Themen 2
I Downloaden einer Datei geht nicht? Allgemeine Java-Themen 16
P Input/Output Ordner löschen --> geht nicht Datei --> Ja Allgemeine Java-Themen 6
G JTable mit Keylistener geht nicht Allgemeine Java-Themen 3
C Zugriff auf private Methode per reflection geht nicht mehr Allgemeine Java-Themen 3
R Geht das? JRE 1.4 global, 1.6.20 nur für eine Anwendung? Allgemeine Java-Themen 9
ruutaiokwu junit mit annotations geht nicht? Allgemeine Java-Themen 5
F externe module. geht das in Java? Allgemeine Java-Themen 3
N Java geht nicht mehr zu löschen Allgemeine Java-Themen 5
M XML-Datei geht bei voller Festplatte verloren Allgemeine Java-Themen 4
DStrohma Daten in JAR speichern geht nicht?? Allgemeine Java-Themen 22
S Viele Bilder -> Speicher ausgelastet? / (De-)serialisierung geht nicht mehr richtig Allgemeine Java-Themen 8
B Komplettes Projekt als UML Diagramm mit eUML...geht das? Allgemeine Java-Themen 10
N List<? implements "Interface"> geht nicht Allgemeine Java-Themen 13
A Javakonsolenfenster geht gleich wieder zu Allgemeine Java-Themen 6
M Übergebener String bearbeiten geht nicht. Allgemeine Java-Themen 4
D iText und Table.setTableFitsPage(); geht nicht Allgemeine Java-Themen 12
E Cipher geht mal und mal nicht Allgemeine Java-Themen 3
G Datei löschen nach kopieren geht nicht Allgemeine Java-Themen 5
A Standalone geht - JSP u. Bean nicht Allgemeine Java-Themen 6
D Jar auf Mac starten geht nicht Allgemeine Java-Themen 3
M Klasse Desktop geht nicht mehr (EXCEPTION_ACCESS_VIOLATION) Allgemeine Java-Themen 9
M ireport (Jasper Report) geht nur auf meinen Rechner Allgemeine Java-Themen 3
S Rechner formatiert - nichts geht mehr. Allgemeine Java-Themen 2
S Apache Commons Net geht nicht Allgemeine Java-Themen 5
zilti Wieso geht der StreamReader/Writer nicht? Allgemeine Java-Themen 5
T Geht das vielleicht noch einfacher? Allgemeine Java-Themen 7
M commapi unter vista, geht das? Allgemeine Java-Themen 4
V JavaProgramm von Konsole starten geht nichtmehr Allgemeine Java-Themen 4
V JVM OutofMemory Linux geht, windows nicht Allgemeine Java-Themen 3
H Vector<T>[] vecs = new Vector<T>[10]; geht nicht Allgemeine Java-Themen 2
K java geht beim chatten nicht? Allgemeine Java-Themen 2
G Mit Java auf windows 2003 userrechte zugreifen geht sowas ? Allgemeine Java-Themen 2
R Drag und Drop von externen Files geht nur als Application Allgemeine Java-Themen 2
O Input stream geht net Allgemeine Java-Themen 2
J Threads, Doppelpufferung --> Beispiel gefunden, geht net Allgemeine Java-Themen 16
P rar.exe und variablenparameter als String geht net Allgemeine Java-Themen 4
G Da Jikes nicht mit java 5 geht, gibt es eine andere. Allgemeine Java-Themen 4
TheJavaKid warum geht das nicht? Allgemeine Java-Themen 14
G setLastModified geht nicht Allgemeine Java-Themen 8
H Ausführungsgeschwindigkeit reduzieren. Geht das? .. Allgemeine Java-Themen 21
G parseInt geht nicht Allgemeine Java-Themen 10
K Mit Java kleine Freeware Programme erstellen. Geht das? Allgemeine Java-Themen 16
G Konsoleneingabe: vordefinierte werte setzen? geht das? Allgemeine Java-Themen 4
André B. geht das? Allgemeine Java-Themen 6
L JTable: Wenn Zeile markiert dann Meldung. geht nicht Allgemeine Java-Themen 4
G Mouselistener geht aber danach Fehler bei JOptionPane Allgemeine Java-Themen 4
K Object casting geht nicht. Allgemeine Java-Themen 3
M Systemzeit der Java VM geht falsch Allgemeine Java-Themen 4
K KeyEvent in eigenem Component geht nicht Allgemeine Java-Themen 3
L Jar-Datei aus Eclipse geht nicht Allgemeine Java-Themen 2
C Was geht noch? Allgemeine Java-Themen 13
P Nur eine Instanz eines Programms zulassen, wie geht das? Allgemeine Java-Themen 15
G Geht das? Allgemeine Java-Themen 4
V StreamTokenizer ???? Wie geht das Allgemeine Java-Themen 3
kodela StatusBar-Anzeigen auch in Log-Datei ausgeben Allgemeine Java-Themen 3
Thomasneuling Java Jar datei erstellen, von Projekt, dass auch Javafx Dateien, FXML Dateien und CSS Dateien, sowie Bilder enthält? Allgemeine Java-Themen 14
S HTML einer Webseite 1:1 so bekommen wie es auch der Browser anzeigt? Allgemeine Java-Themen 14
N nicht static und auch nicht new Allgemeine Java-Themen 3
M Openjdk - gibt es auch eine Openjre? Allgemeine Java-Themen 7
S Java.exe exestiert, aber irgendwie auch nicht Allgemeine Java-Themen 11
J Eigene Api erstellen und dann auch verwenden - Ordnerstruktur Allgemeine Java-Themen 1
Thallius Neuen Prozess starten, der auch nach Beedingung des Starter-Prozesses weiterläuft? Allgemeine Java-Themen 5
L Variable auch in der function verfügbar machen? Allgemeine Java-Themen 4
Zettelkasten JAR-Datei kann bei Freund auch nicht mit CMD ausgeführt werden Allgemeine Java-Themen 4
A Classpath ResourceBundle Problem bzgl. Pfade bzw. Pfade (auch in Eclipse) generell? Allgemeine Java-Themen 7
T auch bei neustart laufen... Allgemeine Java-Themen 3
i<3java [Groovy/Grails](oder auch java) Mögliche Performance Probleme bei Mailversendung Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben