Daten zurückgeben oder im Objekt behalten?



  • Ich habe mir eine Klasse geschrieben, welche Daten sortieren kann genau genommen
    sind es derzeit nur Integer-Zahlen.
    Ich sortiere sie aber nicht wirklich sondern zähle nur wie oft sie vorkommen und
    gebe danach so oft eben die entsprechende Zahl aus. Daher habe ich ein 2D-Array
    indem einmal die Zahl und einmal die Anzahl steht.
    Wenn ich die Zahlen nun "pseudo-sortiert" habe, sollte ich sie dann im Objekt behalten
    und die Arbeit über das Objekt an den Daten ermöglichen oder sollte ich das
    2d-Array als Rückgabetyp der methode sort verwenden?
    Oder sollte ich die Möglichkeit offen lassen, dass man das Array über eine Methode
    ausgeben kann und über weitere mit ihm arbeiten und eine welche aus dem 2d-array
    ein Array erzeugt welches die Zahlen sortiert in einem Array zurückliefert?

    Bin derzeit noch unschlüssig wie es am besten wäre.
    Bis jetzt kann ich nur Zahlen sortieren bei welchen ich den min und max Wert
    im Array kenne, möchte aber noch die Möglichkeit einbauen, dass dies auch
    ohne jeglichen Angaben geht.
    Dazu benötige ich aber eine Struktur welcher ich jede Zahl übergebe und welche
    Die Zahl entsprechend einsortiert, hierbei wäre eine doppelt verkettete Liste
    wohl am besten, aber wie macht man so etwas in Java, da gibts ja keine Zeiger.
    Die Liste muss immer sortiert sein, da ich sonst nicht die binäre Suche verwenden
    kann und der Sortiervorgang ja schnell sein soll.

    Hoffe ihr könnt mir einige Tipps geben 🙂

    Hier könnt ihr euch mein bisherigen Quellcoe ansehen, er ist allerdings derzeit
    noch nicht der beste.

    class test {
    
    	private int zahlen[][]; // Assoc Array welches die Anzahl der Zahlen speichert
    	private int min;		// Minimalwert im Array
    	private boolean known; // Sind die Min und Max Werte in buffer bekannt?
    
    	private int i,loop; // Zählervariablen
    
    	// Informationen über das Array sind unbekannt
    	test () {
    		known = false;
    	}
    	// Informationen über Array sind bekannt
    	// Das Assoc Array mit den min bis max Werten füllen
    	test (int min, int max) {
    		zahlen = new int[max][max];
    		this.min = min;
    		known = true;
    
    		for (i = min, loop = 0; i <= max; i++, loop++) 
    			zahlen[loop][0] = i;
    
    	}
    
    	// Nimmt das zu sortierende Array entgegen
    	public boolean sort (int sort_array[]) {
    
    		if (sortieren (sort_array))
    			return true;
    		else
    			return false;
    	}
    
    	public void output () {
    
    		for (int i = 0; i < zahlen.length; i++) {
    			for (int j = zahlen[i][1]; j > 0; j--)
    			 System.out.println (zahlen[i][0]+ " ");
    		}
    	}
    
    	// Sortiert das Array
    	private boolean sortieren (int sort_array[]) {
    
    		for (int i = 0; i < sort_array.length; i++) {
    			zahlen[sort_array[i]-min][1]++;
    		}
    		return true;
    	}
    
    }
    

    Eine Frage, ich habe in der Datei noch eine Klasse Sortieren, welche ich zum
    testen meiner Klasse test benutze, wenn ich vor test public oder private schreibe
    akzeptiert Java das nicht, nur wenn ich es weglasse, ich dachte eigentlich,
    dass alle Klassen automatisch public sind, aber er meckert bei public ja.
    Die andere Klasse muss ja Public sein weil da die main-methode steht



    1. klassensichtbarkeit: wenn du nicht public schreibst ist das "oeffentlich fuer das aktuelle package" - im gegensatz zu public "oeffentlich fuer alle klassen"

    2. sicher kannst du in java listen machen - ohne probleme
      du hast ja referenzen was zeiger sind

    eine kleine testklasse

    public node{
       private node NextNode = null;
       private node LastNode = null;
    
       public node(){
       }
    
       public void setNextNode(node next){
           NextNode = next;
       }
    
       public void setLastNode(node before){
           LastNode = before;
       }
    }
    

    das ist eine simple liste - die man selber aufbauen kann
    ich glaub mehr brauchst du jetzt mal nicht

    es gibt auch jede menge vorgefertigte klassen - aber das willst du ja glaube ich nicht

    1. kommt darauf an
      normalerweise wuerde ich sagen nein und wuerde die funktion static machen
      aber wenn du das ergebnis mehrmals brauchst kannst du es ruhig speichern

    cu

    gomberl



  • Ok, dann muss ich für die Referenzen einfach das Objekt übergeben?

    Zu deinem dritten Punkt, ich möchte ja das Array sortieren und in den meisten
    Fällen möchte man es ja nicht nur zur Ausgabe sortiert haben sondern auch damit
    anschließend arbeiten.
    Wenn ich die Funktion static mache, was hätte ich dann davon? Verstehe gerade nicht
    worauf du hinauswillst.

    Und nein ich mache es ganz gern selbst, auch wenn die vorgefertigen sicher schneller
    sind, aber ich will mich ja etwas mehr in Java und OOP einarbeiten.



  • Ok, dann muss ich für die Referenzen einfach das Objekt übergeben?

    genau.
    du uebergibst naemlich nicht das objekt - du uebergibst die referenz auf das objekt
    es gibt in java nur referenzen auf objekte

    hier ein beispiel:

    JPanel pan = null; // deklariert eine referenz auf null
       new JPanel();     // erstellt ein neues objekt
       JPanel pan2 = new JPanel(); // deklariert eine referenz und laesst sie auf ein neues objekt zeigen.
    

    Zu deinem dritten Punkt, ich möchte ja das Array sortieren und in den meisten
    Fällen möchte man es ja nicht nur zur Ausgabe sortiert haben sondern auch damit
    anschließend arbeiten.

    wie du bei den static methoden gleich sehen wirst kannst du methoden schreiben die objekt unabhaengig sind
    du sagst zB du hast eine klasse ListenObjekt
    und diese bringt auch gleich eine sortierfunktion mit
    nun kann aber das objekt ListenObjekt sich nicht sortieren - es ist ja nur eines
    also schreibst du diese methode static
    uebergibst ihr deinen root node und bekommst als return wert die sortierte liste
    aber die liste bleibt nicht im objekt gespeichert

    Wenn ich die Funktion static mache, was hätte ich dann davon? Verstehe gerade nicht worauf du hinauswillst.

    wenn du nichts speicherst - keinen status im objekt hast oder gar kein objekt brauchst weil du einfach einen algorithmus zum sortieren von objekten schreibst dann kannst du das static machen
    das heisst eine methode die der klasse und nicht einer instanz (objekt) zugeordnet ist

    class testclass{
         public Vector static reverseVector(Vector v){
           ....
         }
     }
    
    //kann aufgerufen werden mit
       testclass.reverseVector(MyVector); // also mit dem klassenname - es wurde kein objekt instanziert
    


  • Ok jetzt verstehe ich wieso static, das macht Sinn 🙂
    Dann werd ich mich mal an die Arbeit machen hoffe nur, dass meine Idee auch
    funktioniert, wenn ich min und max nicht mit angebe.
    Was mir bei der Arbeit einfiel, ist es schneller solche eine Liste zu verwenden
    oder einfach in dem zu sortierenden Array min und max zu ermitteln?
    Ich müsste dann das Array 1mal durchlaufen und für jedes Element 1-2 mal vergleichen.

    Dürfte evt. sogar schneller sein oder?



  • das kommt darauf an

    also listen haben gegenueber arrays den vorteil bei einfuege und loeschoperationen schneller zu sein
    wobei arrays bei straight foward suchen schneller sind

    allerdings kann man ja viele spielereien machen von indizes bis weiss der teufel was

    zu deiner problemstellung
    als generell waere es eher ratsam es mittels liste zu machen - allerdings muss man sagen das ich hier an extrem grosse element mengen denke

    ansonsten geht es sicher mit arrays

    am besten du machst beides und machst dann einen performance vergleich - da kansnt du gleich ueben

    wenn du arrays richtig sortieren willst gibt es viele methoden vom bubble sort (simple aber langsam) zu sehr aufwendigen sortieralgorithmen

    und wenn es dann wirklich um schnellen zugriff geht dann nimmt man auch keine arrays sondern baeume
    aber das ist jetzt alles weit weg

    mach einmal dieses program dann koennen wir uns darueber unterhalten was man so alles tunen kann



  • Ok, bubble sort kenn ich und den Rest, aber ich denke richtig Optimiert ist das
    zählen schneller als jeder Vergleich der auf austauschen basiert.
    Sollte ich auch für den Fall wo min/max bekannt ist bereits ein Baum verwenden
    oder eine Liste?
    Ich werde es mal versuchen.



  • Wollte eben mein Programm nun erweitern mit einem unbekannten Array zu Arbeiten
    bekomme jedoch folgenden Fehler:

    Exception in thread "main" java.lang.NullPointerException
    at myprojects.sortieren.test.sortieren(Sortieren.java:78)
    at myprojects.sortieren.test.sort_unknown(Sortieren.java:96)
    at myprojects.sortieren.test.sort(Sortieren.java:59)
    at myprojects.sortieren.Sortieren.main(Sortieren.java:23)

    Hier mein Quellcode:

    package myprojects.sortieren;
    
    import java.awt.*;
    
    public class Sortieren {
    
    	public static void main (String args[]){
    
    		int array[] = {3,5,4,2,6,6};
    
    		test tester = new test ();
    		tester.sort (array);
    		tester.output ();
    	}
    }
    
    class test {
    
    	private int zahlen[][]; // Assoc Array welches die Anzahl der Zahlen speichert
    	private int min;		// Minimalwert im Array
    	private int max;		// Maximalwert im Array
    	private boolean known; // Sind die Min und Max Werte in buffer bekannt?
    
    	private int i,loop; // Zählervariablen
    
    	// Informationen über das Array sind unbekannt
    	test () {
    		known = false;
    	}
    	// Informationen über Array sind bekannt
    	// Das Assoc Array mit den min bis max Werten füllen
    	test (int min, int max) {
    		zahlen = new int[max][max];
    		this.min = min;
    		known = true;
    
    		for (i = min, loop = 0; i <= max; i++, loop++) 
    			zahlen[loop][0] = i;
    
    	}
    
    	// Nimmt das zu sortierende Array entgegen
    	public boolean sort (int sort_array[]) {
    
    		if (known == true) 
    			sortieren (sort_array);
    		else if (known == false)
    			sort_unknown (sort_array);
    		else
    			System.out.println ("Fehler in public boolean sort (int sort_array[])");
    
    		return true;
    	}
    
    	public void output () {
    
    		for (int i = 0; i < zahlen.length; i++) {
    			for (int j = zahlen[i][1]; j > 0; j--)
    			 System.out.println (zahlen[i][0]+ " ");
    		}
    	}
    
    	// Sortiert das Array
    	private boolean sortieren (int sort_array[]) {
    
    		for (int i = 0; i < sort_array.length; i++) {
    			zahlen[sort_array[i]-min][1]++;
    		}
    		return true;
    	}
    
    	// Informationen zum sortieren beschaffen
    	private boolean sort_unknown (int sort_array[]) {
    
    		// Min und Max Werte im Array ermitteln
    		min = 0;
    		max = 0;
    		for (int i = 0; i < sort_array.length; i++) {
    			if (sort_array[i] < min)
    				min = sort_array[i];
    			if (sort_array[i] > max)
    				max = sort_array[i];
    		}
    
    		sortieren (sort_array);
    
    		return true;
    	}
    
    }
    

    Liegt dies daran, dass in diesem Fall das Array zahlen noch nicht initialisiert
    wurde?

    Edit:
    Noch etwas sobald ich über 1000Elemente eines Arrays sortieren möchte erhalt
    ich einen OutOfMemory Error, dabei habe ich mit Algorithmen in C zum testen schon 10mio Elemente verwendet ohne Fehler.



  • schick mir doch das file auf meine email adresse - das sollte moeglich sein ueber das profil - hier noch einmal in klarschrift - damit kein spam robot mich in der liste hat
    d punkt gombotz at gmx punkt at

    wegen dem speicher

    du wirst wohl ziemlich viel speicher noch haben auf den gezeigt wird

    dementsprechend wuerde ich die garbage collection händisch anwerfen

    lg


Anmelden zum Antworten