komplizierter Comparator (IllegalArgumentException)

toki79

Neues Mitglied
Hi,

ich möchte einen Comparator schreiben, der 10000 Dateipfade sortiert ausgibt. Es gibt beliebige Abhängigkeiten zwischen diesen Dateien, die in der Form einem Liste von Dependency Objekten vorliegen.

Code:
public class Dependency {
    public String actual;
    public String parent;
    
    public Dependency(String actual, String parent) {
    	this.actual = actual;
    	this.parent = parent;
    }
    
    public String toString() {
    	return actual + " -> " + parent;
    }
}

Dann habe ich eine Klasse MasterScriptComparator, welche die Sortieraufgabe übernimmt. Wenn eine Dependency vorliegt, soll nach ihr sortiert werden. Danach ist mir die Sortierung eigentlich erstmal egal, aber ich sortiere dann noch nach Objekttyp (Tabelle, View, Prozedur, etc.)

Es funktioniert nicht. Leider bekomme ich einen: IllegalArgumentException: Comparison method violates its general contract Hat jemand einen Ansatz, wie ich die Methode umschreiben sollte?

Code:
	private final String[] types = new String[] {
		"Tablespaces",
		"Roles",
		"Users",
		"UserObjectPrivileges",
		"ObjectTypes",
		"Database Links",
		"Synonyms",
		"Packages",
		"Functions",
		"Sequences",
		"Constraints",
		"Indexes",
		"Materialized Views",
		"Package Bodies",
		"Procedures",
		"Tables",
		"Triggers",
		"Views"
	};

@Override
	public int compare(String f1, String f2) {	
		f1 = f1.replace("\\", "/").replace("@","").trim();
		f2 = f2.replace("\\", "/").replace("@","").trim();
		//System.out.println("Compare " + f1 + " with " + f2);
		
		File ff1 = new File(f1);
		File ff2 = new File(f2);		
		
		//System.out.println("COMPARE : " + f1 + " vs. " + f2);
					
		boolean[] depExists = new boolean[2];
		for (Iterator<Dependency> iter = this.dependencies.iterator(); iter.hasNext(); ) {
			Dependency d = iter.next();
			
			//System.out.println(" f1: " + f1 + " f2: " + f2 + " Checking: " +d);
			if (d.actual.equalsIgnoreCase(f1)
					&& d.parent.equalsIgnoreCase(f2)
					) {
				//System.out.println(f1 + " ist abh. von " + f2 + " Dep: " + d);
			    return 1;
			}
			if (d.actual.equalsIgnoreCase(f2)
					&& d.parent.equalsIgnoreCase(f1)
					) {
				//System.out.println(f2 + " ist abh. von " + f1 + " Dep: " + d);
			    return -1;
			}
			
			if (d.actual.equalsIgnoreCase(f1))
				depExists[0] = true;
			if (d.actual.equalsIgnoreCase(f2))
				depExists[1] = true;

		}
		
		
		if (!depExists[0] && !depExists[1])
		for (int i = 0; i < types.length; i++) {
			String part = "/" + types[i] + "/";	
			if (f1.contains(part)  && !f2.contains(part)) {
				//System.out.println("Return -1, da f1 like " + types[i]);
				return -1;
			}
			    
			if (f2.contains(part) && !f1.contains(part)) {
				//System.out.println("Return 1, da f2 like " + types[i]);
				return 1;
			}

		}
	
		
		return 1;
	}
 
Zuletzt bearbeitet:
hmm... sollte eine Dependency nicht als Parent wieder eine Dependency haben?

Dann könntest du mit Dependency.getParent().getParent()... so tief du willst in den Baum reingehen (bzw dir einen Baum bauen)

erstmal das..

du könntest dann nur actual vergleichen - einfach mit equals - aber gleichzeitig getParent() rekursiv durchgehen (bis root?) und dort jeweils actual vergleichen.

Dann hättest du einen Vergleich auf gleicher Ebene und merkst, wenn sich 2 Äste unterscheiden.
 
Was sofort auffällt, ist, dass dein Comparator niemals 0 zurückgibt. Das kann doch nix werden. Denk daran, dass für alle Strings
Code:
s1
und
Code:
s2
gelten muss:
Code:
sgn(compare(s1,s2)) = -sig(compare(s2,s1))
, wobei sgn() die "Vorzeichen-Funktion" sein soll.
 

Neue Themen


Zurück
Oben