Add zu TreeSet Probleme

waldorfmad

Mitglied
Eclipse Kepler SR 1 auf OS X 9.2

Hallo,

wir haben eine Klasse Dataset die Einen Calendar und ein paar Floats hält, also nichts wildes.

Java:
import java.util.*;

/*Diese Klasse repräsentiert eine Datenstruktur, die relevante Werte einer Aktie bezogen auf einen Tag zusammenfasst. Es sollen folgende Werte erfasst werden:
Datum (date), Eröffnungskurs (open), Höchstwert (high), Tiefstwert (low), Endkurs (close)*/

public class Dataset {
	//Initialisierung der Klasse mit den übergebenen Werten bei Erstellung einer neuen Instanz
	public Dataset(Calendar date, double open, double high, double low, double close){
		
		this.date = date;
		this.open = open;
		this.high = high;
		this.low = low;
		this.close = close;
	}
	
	//Deklaration der Variablen
	Calendar date;
	double open;
	double high;
	double low;
	double close;
	
	//Liefert eine Kopie des Datums
	public Calendar getDate() {
		Calendar datecopy = (Calendar) date.clone();
		return datecopy;
	}
	
	//Liefert den Eröffnungswert
	public double getOpen() {
		return open;
	}
	
	//Liefert den Höchstwert
	public double getHigh() {
		return high;
	}
	
	//Liefert den Tiefstwert
	public double getLow() {
		return low;
	}
	
	//Liefert den Tagesendwert
	public double getClose() {
		return close;
	}
	
	//Vergleicht zwei Objekte Dataset Instanzen miteinander.
	public boolean equals(Dataset other){
		if (
				(date.get(Calendar.DAY_OF_MONTH) == other.date.get(Calendar.DAY_OF_MONTH))&&
				(date.get(Calendar.MONTH) == other.date.get(Calendar.MONTH))&&
				(date.get(Calendar.YEAR) == other.date.get(Calendar.YEAR))&&
				(open == other.open) && 
				(high == other.high) && 
				(low == other.low) && 
				(close == other.close))
			return true;
			else return false;
	}
	
	//Anpassung der hashCode Funktion an die equals Funktion
	public int hashCode() {
		int hc = 17;
		
		hc = hc + date.get(Calendar.DAY_OF_MONTH);
		hc = hc + date.get(Calendar.MONTH);
		hc = hc + date.get(Calendar.YEAR);
		
		long temp = ((open == 0.0) ? 0L: Double.doubleToLongBits(open));
		hc = hc + (int) (temp ^ (temp >>> 32));
		
		temp = ((high == 0.0) ? 0L: Double.doubleToLongBits(high));
		hc = hc + (int) (temp ^ (temp >>> 32));
		
		temp = ((low == 0.0) ? 0L: Double.doubleToLongBits(low));
		hc = hc + (int) (temp ^ (temp >>> 32));
		
		temp = ((close == 0.0) ? 0L: Double.doubleToLongBits(close));
		hc = hc + (int) (temp ^ (temp >>> 32));
		
		return hc;
	}
	
	//Liefert eine Textrepräsentation des Datensatzes
	public String toString() {
		return date.get(Calendar.DAY_OF_MONTH)+"."+(date.get(Calendar.MONTH)+1)+"."+date.get(Calendar.YEAR)+";" + open+";"+high+";"+low+";"+close;
	}
	}


Der Comparator für diese Datasets sieht so aus und soll nach dem Datum im Calendar ordnen.:

Java:
public class DatasetComparator implements Comparator<Dataset>{
@Override public int compare (Dataset D1, Dataset D2)
{//System.out.println("Comp: "+D1+"  "+D2);
	if (D1.date.after(D2.date)) { return -1;}
	if (D1.date.before(D2.date)) {return 1;}
	else {return 0;}
}
}

Von dieser Klasse haben wir einen TreeSet angelegt. Beim Einfügen eines DataSets in den TreeSet mit add scheint der Comparator nicht richtig zu greifen. Das ganze läuft in einer Schleife. Mit i zähle ich die Schleifendurchläufe.

Java:
 //Dataset bauen
	    	        Dataset DS = new Dataset (cal, open, high, low, close);
	    	        //TreeSet der datasets bauen
	    	        System.out.println(i+" DS vor: "+DS);

gibt brav "1 DS vor: 20.8.2013;20.0;8.09;7.77;7.94" aus.

Nun kommt das Ding in den TreeSet:

Java:
 datasets.add(DS);

und ich lese den TreeSet aus:

Java:
 System.out.println(datasets+"------"+i+" "+Name);

Beim ersten zufügen geht alles gut.

[20.8.2013;20.0;8.09;7.77;7.94]------1 Commerzbank, also genau wie der Dataset vor dem add...

Im zweiten Schleifendurchlauf kommt nun der nächste Dataset:

2 DS vor: 19.8.2013;19.0;8.55;8.1;8.15

nach dem add steht nun aber im Dataset:

[19.8.2013;20.0;8.09;7.77;7.94]------2 Commerzbank

Es hat sich also nur das Datum vorne geändert, aber die floats sind gleich geblieben.

Wenn ich mir im Comparator die beiden Eingangsobjekte anschaue ist dort schon das gleiche Problem:

Comp: 19.8.2013;19.0;8.55;8.1;8.15 19.8.2013;20.0;8.09;7.77;7.94


Damit fällt der Comparator auf die Nase, nimmt für die eigentlich verschiednen Objekte das gleiche (falsche) Datum an and gibt zurück, dass die Objekte anhand des Datums gleich sind. So wird das Dataset also nicht in den TreeSet gepackt.

Hat jemand eine Idee, was da falsch läuft?

Danke vielmals

Oliver
 
Gibst du beim Erzeugen des TreeSets denn auch den Comparator bzw. eine Instanz davon mit an? Dieser Teil des Codes ist nicht sichtbar, deshalb erstmal diese grundlegenden Frage, bevor ich den Rest lese 🙂
 
Kannst du mal zeigen, wie du die Datensätze baust? Erzeugst du für jedes eine neue Calendar-Instanz oder modifizierst du mit der Schleife eine bestehende Instanz? Dann würdest du nämlich den Calendar aller bestehenden Objekte immer wieder ändern, sodass am Ende alle identisch wären.
 
Ich schicke Dir mal die ganze Klasse. Ich denke, dass ich den Calendar wirklich in jedem Durchlauf ändere....
Das ist in Zeile 74

Java:
import java.io.*;
import java.util.*;
import java.text.*;

public class CSVShareImporter implements ShareImporter{
	
	
	//prüft, ob der String mit "Share" beginnt
	public boolean isNewShare (String string){
		if (string.startsWith("SHARE"))
		{return true;}
		else
		{return false;}
	}

	
	public ShareCollection load(InputStream is) throws IOException{
		
		String Name;
		String NameString = "";
		 String DateString;
		 String TempString = "";
		 Date date = null;
		 Calendar cal = Calendar.getInstance(); //Hier ist der Calendar erzeugt
		 Double open;
		 Double high;
		 Double low;
		 Double close;
		
	      ShareCollection SC = new ShareCollection();
	      TreeSet<Dataset> datasets = new TreeSet<Dataset>(new DatasetComparator());
	      Scanner scanner = new Scanner(is).useDelimiter(";");
	      
	     
	  

	        scanner.nextLine();  // überliest date;open;high;low;close
	        //Mach hin solange noch Zeilen da sind
	        while (scanner.hasNextLine()){
	        	
	        	
	        	  
	        	//Nächste Zeile in NameString merken wenn noch leer
	        	if (NameString == "")
	        	{NameString = scanner.nextLine();}
	        	else
	        	{NameString = TempString;} //ansonsten die letzte gelesene Zeile 
	        	
	        	//Auf die Zeile im String einen neuen Scanner
	        	Scanner StringScanner = new Scanner(NameString).useDelimiter(";");
	        	//In dem String das "SHARE" überlesen
	        	StringScanner.next();
	        	//Und nun den Namen merken
	        	Name=StringScanner.next();
	    
	        	

	        	// System.out.println("Name "+Name);
	        	int i = 0;
	      
	        	// wenn es keine Zeile mit "SHARE" ist, die nächste Zeile merken
	        	while (!isNewShare(TempString = scanner.nextLine()) && scanner.hasNext()){ //!!! Warum wird letzte Zeile nicht gelesen?
	        	i++;
	        		StringScanner = new Scanner(TempString).useDelimiter(";");
	    	        DateString = StringScanner.next();
	    	      //String in Date wandeln
	    	        try{
	    	        SimpleDateFormat sdfToDate = new SimpleDateFormat(
	                        "dd.MM.yyyy");
	                date = sdfToDate.parse(DateString);}
	    	        catch (ParseException exc) {System.out.println(exc);}
	    	        
	    	      //Date in den Calendar
	    	        cal.setTime(date); //Hier meinst Du wohl?????
	    	        open = Double.parseDouble(StringScanner.next());
	    	        high = Double.parseDouble(StringScanner.next());
	    	        low = Double.parseDouble(StringScanner.next());
	    	        close = Double.parseDouble(StringScanner.next());
	    	        
	    	     
	    	        //Dataset bauen
	    	        Dataset DS = new Dataset (cal, open, high, low, close);
	    	        //TreeSet der datasets bauen
	    	        System.out.println(i+" DS vor: "+DS);
	    	       datasets.add(DS);
	    	        //System.out.println(i+" DS nach: "+DS);
	    	        System.out.println(datasets+"------"+i+" "+Name);
	    	        //!!!Warum überschreibt der hier?
	        	}
	        	
	        	
	        
	            //System.out.println("Nach Schleife: "+datasets);
    	        Share share = new Share(Name, datasets);
    	        //System.out.println(share.toString());
  
	        }
	      
	        return SC;
	        }//Method load ends
}//Class ends
 
Zuletzt bearbeitet:
Ja, das dürfte genau das Problem sein. Entweder benutzt du im Konstruktor auch clone, so wie es der Getter macht, oder du erzeugt von außen neue Objekte und modifzierst nicht das bestehende 🙂
 
Wow, danke....

genau das war es. Blöder Fehler.... Ich erzeuge jetzt in jedem Durchlauf einen neuen Calendar.

Java:
//Date in den Calendar
	    	        Calendar cal = Calendar.getInstance();
	    	        cal.setTime(date);
	    	        open = Double.parseDouble(StringScanner.next());
	    	        high = Double.parseDouble(StringScanner.next());
	    	        low = Double.parseDouble(StringScanner.next());
	    	        close = Double.parseDouble(StringScanner.next());

und nun geht es.

Danke vielmals. Das war eine tolle Hilfe. Chapeau 🙂

Oliver
 

Zurück
Oben