ArrayList: Werte aussortieren

Status
Nicht offen für weitere Antworten.

magic_halli

Bekanntes Mitglied
Hi,

ich sitz schon ewig an einer Sache und komme einfach nicht zu Rande.
Ich lese mir in eine ArrayList 'matches' aus einem Verzeichnis alle Dateinamen ein, die ".drw." im Namen enthalten, z.B. test.drw.1.
Jetzt kann es aber sein, dass von einer Datei mehrere Einträge in matches vorhanden sind, die sich lediglich in der Ziffer hinter der Dateiendung (drw) unterscheiden.
Also z.B. kann matches so aussehen:
Code:
test.drw.1
test.drw.3
test.drw.5
test.drw.2
a.drw.1
a.drw.2
a.drw.4
...
Ich will aber als Endergebnis, dass nur noch der Dateiname mit der höchsten Zahl hinter der Dateiendung in meiner ArrayList steht, also so:
Code:
test.drw.5
a.drw.4

Hier ist mal mein Code, der mir erstmal alle Dateinamen eines Verzeichnisses in meine ArrayList schreibt:
Code:
String path, drwName, find;
ArrayList matches = new ArrayList();
ArrayList help = new ArrayList();
		
    	try{
    		path = curSession.GetCurrentDirectory();
    		find = ".drw.";
    		File f = new File(path);
    		File[] fileArray = f.listFiles();
    		if(fileArray != null){
    			for(int i=0;i<fileArray.length;i++){
    				if(fileArray[i].getName().indexOf(find) != -1){
    					drwName = fileArray[i].getName();
    					//Dateiname der drw(s) stehen in matches
    					matches.add(drwName);
      				}
    			}
    		}    		
    	}
...

Wie kann ich mein Vorhaben am Besten umsetzen?

Gruß.
 
sortiere die Liste nach den Dateinamen,
dann hast du auf jeden Fall alle
dateiname.endung.x
zusammen,

ein Wechsel zwischen solchen Gruppen stellst du mit einer Änderung im Dateinamen vor dem Punkt fest,

von einer solchen Gruppe musst du nun den höchsten wählen,
sind die Nummern nur einstellig oder im sortierbaren Format wie 01 bis 99,
dann reicht es, den ersten oder letzten der Sortierung zu nehmen
-> Sortierung: 04 < 12 < 57

ansonsten hast du ein Problem mit der Stringsortierung:
12 < 4 < 57

also die Zahlen herausnehmen und entweder als String vergleichen (mit eigenem Verfahren, z.B. Länge anschauen)
oder in int umwandeln und dann sortieren lassen
 
Hi,

[/quote]ein Wechsel zwischen solchen Gruppen stellst du mit einer Änderung im Dateinamen vor dem Punkt fest,...
Ich habe meine ArrayList mittels Comparator nach Namen sortiert vorliegen.
Ich weiß aber nicht so recht, wie ich das umsetzen kann, um eine Unterscheidung nach Gruppen (gleiche Dateinamen) vorzunehmen, damit ich dann später daraus die Nummern am Ende der Dateinamen zu vergleichen.

Könnt ihr mir nen Tip geben, wie ich da am Besten rangehen könnte?!
 
zum Quoten drücke mal auf einen Zitieren-Button, dann siehst du wie man das schreiben muss 😉

wenn du
dateiA.drw.1
von
dateiB.drw.1
nicht unterscheiden kannst, was soll dann die ganze Aufgabe?..

mit indexOf/ lastIndexOf kannst du die Position von Teilstrings bestimmen, z.B. vom ersten oder letzten Punkt

mit substring(start, ende) kannst du Teilstrings bestimmen und die musst du dann mit equals vergleichen (nicht mit == !)
 
Hi,

ich habe meine ArrayList sortiert (mittels Comparator), sodass nun die Dateinamen in Gruppen untereinanderstehen. Dann habe ich aus jeder Zeile der Liste den Namensteil (z.B. dateiname.endung) und die abschließende Zahl x in jeweils einer Variable gespeichert:
Code:
//Sortierung von ArrayList matches mittels Comparator
Collections.sort(matches, comparator_test);
//jeden Eintrag der ArrayList zerlegen in dateiname.endung(part1) und Ziffer (part2 bzw. i_part2)
	for(int j=0;j<matches.size();j++){
		String name = matches.get(j).toString();
		String part1 = name.substring(0, name.lastIndexOf("."));
		String part2 = name.substring(name.lastIndexOf(".") + 1, name.length());
		//part2 von String in Integerwert umwandeln
		int i_part2 = Integer.parseInt(part2);
   }
Wie kann ich nun aber die Namensteile (part1) vergleichen, um einen Gruppenwechsel herauszufinden und den Namen mit der höchsten separierten Ziffer (i_part2) wieder in eine ArrayList speichern?
Ich probiere hier nun schon ewig rum und nix will so recht klappen. :?

Gruß und Danke.
 
was hat dies mit Java zu tun?
Programmieren ist hauptsächlich Denkarbeit!

du hast also eine Liste
a
a
a
b
die du nacheinander durchläufst,
dann merkst du dir immer das letzte Element und vergleichst es mit dem aktuellen, fertig

1. Durchlauf: letztes Element null, aktuelles a -> Spezialfall, zwar ein Wechsel, aber nix zu tun,
außer a als neues letztes Element zu speichern,
und aufpassen dass es keine NullPointerException beim Vergleich gibt

2. Durchlauf: letztes Element a, aktuelles a -> nix zu tun
3. Durchlauf: letztes Element a, aktuelles a -> nix zu tun
4. Durchlauf: letztes Element a, aktuelles b -> Wechsel!,
die Gruppe a abschließend bearbeitetn und b als neues letztes Element speichern
 
Ok, danke für den Denkanstoß... ich werd mich da jetzt drüber machen.
Das alles mache ich in meiner for-Schleife?!

EDIT: Nein, das ganze muss ich im Comparator realisieren, richtig?
 
der Comparator sortiert nur, das hast du fertig

der Rest in der Schleife, parallel zum Feststellen des Gruppenwechsels natürlich innerhalb der Gruppe auch die Ziffern (eine pro Schleifendurchlauf) registrieren und sich die höchste merken
 
Hi,

ich werd jetzt echt bald wahnsinnig - wie kann ich mir bitteschön das letzte Element merken und mit dem aktuellen Element vergleichen? Das alles in meiner for-Schleife von oben?! Ich komm mit diesem Index j einfach nicht zurecht... wahrscheinlich denke ich mal wieder um 5 Ecken zu kompliziert?!
Ich hab jetzt tausend Sachen probiert, aber irgendwie hab ich einen "Gedankenknick"!
Könnte mir mal jemand ein Codesnipplet hierzu geben? Vom Ablauf her bin ich ansonsten voll im Bilde... Nicht falsch verstehen, ich will nicht die Lösung präsentiert haben, nur mal einen Gedankenanstoß in Form von Code, damit ich auch sehe, ob meine bisherigen Bemühungen überhaupt in die richtige Richtung gehen...

Danke und Gruß.
 
Code:
        int[] zahlen = new int[]  {3, 4, 4, 4, 4, 4, 4, 4, 50000, 6};
        int letzteZahl = -1;
        for (int i = 0; i < zahlen.length; i++)
        {
            int aktuelleZahl = zahlen[i];
            System.out.println("alte Zahl: " + letzteZahl + ", neue Zahl: " + aktuelleZahl);
            if (letzteZahl > -1 && letzteZahl != aktuelleZahl)
            {
                System.out.println("Zahlwechsel entdeckt, Differenz: " + (aktuelleZahl - letzteZahl));

            }
            letzteZahl = aktuelleZahl;
        }
 
Besten Dank nochmal... ich habe jetzt (fast) alles lösen können. Es wird jetzt aus jeder "Gruppe von zusammengehörigen Einträgen" der letzte Eintrag in meine neue ArrayList hinzugefügt. Hier mal mein jetziger Code:
Code:
ArrayList matches = new ArrayList();
		ArrayList help = new ArrayList();
		
    	try{
    		path = curSession.GetCurrentDirectory();
    		find = ".drw.";
    		File f = new File(path);
    		File[] fileArray = f.listFiles();
    		if(fileArray != null){
    			for(int i=0;i<fileArray.length;i++){
    				if(fileArray[i].getName().indexOf(find) != -1){
    					//FileExtension drw.1 - .1 abschneiden (nötig?)
    					//String a = fileArray[i].getName().substring(0,fileArray[i].getName().lastIndexOf("."));
    					drwName = fileArray[i].getName();
    					//Dateiname der drw(s) stehen in matches
    					matches.add(drwName);
    				}
    			}
    		} 
    		//Sortierung von matches mittels Comparator
    		Collections.sort(matches, comparator_test);

//ab hier beginnt mein eigentlicher Problemstellungsteil
			String letzterWert = null;
			int letzteZahl = -1;

			//hier den letzten Eintrag aus jeder Gruppe in neue ArrayList speichern
			for(int j=0;j<matches.size();j++){
				String name1 = matches.get(j).toString();
				String part1 = name1.substring(0, name1.lastIndexOf("."));
				String part2 = name1.substring(name1.lastIndexOf(".") + 1, name1.length());
				//Zahlenwert von String in Integerwert umwandeln
				int i_part2 = Integer.parseInt(part2);
				
				String aktuellerWert = part1;
				int aktuelleZahl = i_part2;
				
				if(letzterWert != null && letzterWert.equals(aktuellerWert) != true){
					if(letzteZahl > -1 && letzteZahl != aktuelleZahl){
						help.add(letzterWert + "." + letzteZahl);
					}
				}
				letzteZahl = aktuelleZahl;
				letzterWert = aktuellerWert;
			}
			
			//allerletzten Eintrag hinzufügen
			help.add(matches.get(matches.size()-1));
    	}
Alles klappt jetzt, bis auf... wenn nur ein Eintrag 'Dateiname.Endung.1' vorkommt und danach ein neuer, anderer Eintrag folgt. Dieser eine (einzelne) Eintrag wird nicht mit in meine ArrayList aufgenommen! :cry: Wieso das denn?

Ansonsten muss ich den allerletzten Eintrag aus matches in die neue ArrayList separat, mittels
Code:
purge.add(matches.get(matches.size()-1));
aufnehmen. Aber damit kann ich erstmal leben.

Gruß
 
lasse den Teil mit den Files weg und füge per Hand einige Strings in matches ein so dass das Problem auftritt
(nennt sich "Testen"),
dann kann ich das selber 'testen'
 
Ok, hab mir jetzt ne separate "Testklasse" gebaut - hier sieht man sehr schön die Effekte, was passiert, wenn ein Eintrag nur einmal da ist oder aber mehrmals etc...
Code:
import java.util.ArrayList;

public class Purge {
    
public static void main(String[] args){
	
	ArrayList purge = new ArrayList();
	ArrayList matches = new ArrayList();
	matches.add("A.drw.1");
	matches.add("A.drw.2");
	matches.add("A.drw.3");
	matches.add("B.drw.1");
	//matches.add("B.drw.2");
	matches.add("C.drw.1");
	matches.add("C.drw.2");
	
	String name1, part1, part2, letzterWert = null;
	int j, i_part2, letzteZahl = -1;

	for(j=0;j<matches.size();j++){
		name1 = matches.get(j).toString();
		part1 = name1.substring(0, name1.lastIndexOf("."));
		part2 = name1.substring(name1.lastIndexOf(".") + 1, name1.length());
		//Zahlenwert von String in Integerwert umwandeln
		i_part2 = Integer.parseInt(part2);
		
		String aktuellerWert = part1;
		int aktuelleZahl = i_part2;
		
		if(letzterWert != null && letzterWert.equals(aktuellerWert) != true){
			if(letzteZahl > -1 && letzteZahl != aktuelleZahl){
				purge.add(letzterWert + "." + letzteZahl);
			}
		}
		letzteZahl = aktuelleZahl;
		letzterWert = aktuellerWert;
	}
	
	//allerletzten Eintrag hinzufügen
	purge.add(matches.get(matches.size()-1));
	System.out.println(purge);
	

    }//main
}//class
 
ich habe mal ein paar simple System.out.println eingefügt,
vielleicht siehst du es eher wenn dir das Programm sagt was es tut
(sonst noch mal fragen)
Code:
        ArrayList purge = new ArrayList();
        ArrayList matches = new ArrayList();
        matches.add("A.drw.1");
        matches.add("A.drw.2");
        matches.add("A.drw.3");
        matches.add("B.drw.1");
        // matches.add("B.drw.2");
        matches.add("C.drw.1");
        matches.add("C.drw.2");

        String file, fileName, fileNumber, letzterWert = null;
        int letzteZahl = -1;

        for (int j = 0; j < matches.size(); j++)
        {
            file = matches.get(j).toString();
            fileName = file.substring(0, file.lastIndexOf("."));
            fileNumber = file.substring(file.lastIndexOf(".") + 1, file.length());
            // Zahlenwert von String in Integerwert umwandeln


            int aktuelleZahl = Integer.parseInt(fileNumber);

            if (letzterWert != null && !letzterWert.equals(fileName))
            {
                System.out.println("Dateinamen-Wechsel, letzte Zahl ist: " + letzteZahl + 
                     ", aktuelle Zahl: " + aktuelleZahl);
                if (letzteZahl > -1 && letzteZahl != aktuelleZahl)
                {
                    System.out.println("akzeptiere letzte Zahl");
                    purge.add(letzterWert + "." + letzteZahl);
                }
                else
                {
                    System.out.println("akzeptiere letzte Zahl nicht!");
                }
            }
            System.out.println("setze letzte Zahl auf aktuelleZahl: " + aktuelleZahl);
            letzteZahl = aktuelleZahl;
            letzterWert = fileName;
        }

        // allerletzten Eintrag hinzufügen
        purge.add(matches.get(matches.size() - 1));
        System.out.println(purge);

wenn du im Moment eh immer nur immer ungeprüft 'letzteZahl' mit 'aktuelleZahl' überschreibst
(ohne z.B. diese zu vergleichen), dann kannst du letzteZahl ganz weglassen und einfach die aktuelle Zahl zum Zeitpunkt des Wechsels nehmen,

nur in diesem Fall funktioniert auch das was du am Ende machst,
ansonsten wirds am Ende komplizierter..
 
Guten Morgen,

jetzt hab ich´s endlich hinbekommen. Es war eigentlich nur eine kleine Änderung im else-Zweig der inneren if-Bedingung, aber manchmal sieht man den Wald vor lauter Bäumen nicht :wink:
Hier mal die entgültigen if-Bedingungen:
Code:
if(letzterWert != null && letzterWert.equals(aktuellerWert) != true){
			if(letzteZahl > -1 && letzteZahl != aktuelleZahl){");
				purge.add(letzterWert + "." + letzteZahl);
			}else{;
				purge.add(letzterWert + "." + aktuelleZahl);
			}
}
Hab´s jetzt tausend mal mit verschiedensten Werten und Konstellationen durchgetestet - es klappt!

Tausend Dank auch nochmal an SlaterB :toll:


Gruß und Danke.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben