# Problem mit Klasse



## BC_1992 (31. Aug 2015)

Ich muss eine Aufgabe bearbeiten und habe nur noch Probleme mit einer Klasse.
Beim hochladen auf die Seite, auf der ich die Aufgabe abgebe, werden noch tests ausgeführt.
Hier fehlen mir noch 4 Tests und ich weiß einfach nicht, was das Problem ist.

```
public class CSVShareImporter implements ShareImporter {
     private Scanner scan;
    private Scanner innerScan;

    @Override
     public Collection<Share> load(InputStream is) throws IOException {
     
             scan = new Scanner(is);
             Collection<Share> shares = new ArrayList<Share>();
             String line;
             if(shares.isEmpty()==true){
                 throw new IOException();
             }
             else if ((line=scan.nextLine()) != "date;open;high;low;close") //scanner nimmt die erste Zeile und schaut, ob sie richtis ist
                     throw new IOException();
           
           
             String shareInput = scan.toString(); //restlicher Text wird zu einem langen String gemacht
             String[] splitShareInput = shareInput.split(("SHARE;")); //Langes String zu Array, wird immer an "SHARE" geteilt
             for(String s : splitShareInput){
                     String name;
                     innerScan = new Scanner(s);
                     line = innerScan.nextLine();
                     name = line.split(";")[0]; //Die Zeile wird aufgesplittet und der erste Wert uebernommen
                     ArrayList<Dataset> set = new ArrayList<Dataset>();
                     while ((line=scan.nextLine()) != null) {//solange das jeweilige Array nicht zu Ende ist
                             Calendar date = Calendar.getInstance(); //neuen Calendar erstellen
                             String[] splitLine = line.split(";"); //schon wieder Array
                          
                             date.set(Integer.valueOf(splitLine[0].split(".")[2]), //Datum wird uebergeben, aufgesplittet und die jeweiligen Werte verwendete
                                             Integer.valueOf(splitLine[0].split(".")[1]),
                                             Integer.valueOf(splitLine[0].split(".")[0]));
                             Dataset dataset = new Dataset(date, Integer.parseInt(splitLine[1]),
                                                             Integer.parseInt(splitLine[2]),
                                                             Integer.parseInt(splitLine[3]),
                                                             Integer.parseInt(splitLine[4]));
                             set.add(dataset);
                     }
                     Share share = new Share(name, set);
                     shares.add(share);
             }
             return shares;
          
          

     }
}
```

Die Fehler sehen so aus:

java.lang.AssertionError: An IOException occurred while parsing the following CSV:

und jetzt bei allen möglichen Inhalten wird der Fehler angezeigt.
Ob der Inhalt so :
date;open;high;low;close
SHARE;Adidas;;;
oder so:
date;open;high;low;close
SHARE;Deutsche Telekom;;;
01.01.2013;5.00;4.00;6.00;5.50
ist.

Wo liegt das Problem?


----------



## Dompteur (31. Aug 2015)

Nun, du hast gleich am Anfang folgenden Code:

```
Collection<Share> shares = new ArrayList<Share>();
              String line;
              if(shares.isEmpty()==true){
                  throw new IOException();
              }
```
Du legst "shares" an und fragst dann gleich, ob die Collection leer ist. Da dies immer der Fall ist, endet deine Methode immer mit einer IOException.


----------



## BC_1992 (31. Aug 2015)

Achso okay. Muss ich es dann einfach am Schluss machen?


----------



## Dompteur (31. Aug 2015)

Kommt auf die Anforderung an.
Musst du wirklich eine IOException werfen ?

Du hast außerdem einen Fehler beim String-Vergleich. Strings werden nicht mit == bzw. != verglichen.


----------



## BC_1992 (31. Aug 2015)

Wenn ein Fehler auftritt muss ich eine IOException werfen.
Okay muss ich mir nochmal anschauen:

Ich denke du meintest diese Zeile oder :
line=scan.nextLine()) != "date;open;high;low;close")

Habs verändert.
Mein Problem liegt immer noch bei der Exception


----------



## BC_1992 (31. Aug 2015)

Kann denn niemand helfen? Es scheint nur eine Kleinigkeit zu sein..


----------



## Joose (31. Aug 2015)

BC_1992 hat gesagt.:


> Wenn ein Fehler auftritt muss ich eine IOException werfen.



Mittels try/catch kannst du Fehler/Exceptions abfangen und dann eine Exception deiner Wahl weiterschmeißen.


----------



## BC_1992 (31. Aug 2015)

Aber wenn ich eine try catch Anweisung an der gleichen stelle schmeiße dann krieg ich doch trotzdem die gleiche Fehlermeldung?  

Ich dachte eher daran das ich es an einer anderen Stelle prüfen muss?


----------



## Dompteur (31. Aug 2015)

Du schreibst, dass du es korrigiert hast. Wie ?

Weißt du, *wo* und *warum* die IOException geworfen wird ?
In deinem ursprünglichen Code gibt es ja 2 Stellen, wo du sie wirfst. Außerdem greifst du ja auf einen InputStream zu. Da kann ebenfalls eine IOException geworfen werden.


----------



## BC_1992 (31. Aug 2015)

Das ist die Aufgabenstellung dazu :
Die Klasse ShareCollection liefert mit ihrer toString() Methode, die aktuelle Sammlung im CSV-Format. Implementieren Sie nun die Klasse CSVShareImporter, welche die Schnittstelle ShareImporter implementiert.

Die Klasse soll vom Eingabestrom eine Aktiensammlung im zuvor in den Klassen Dataset, Share und ShareCollection definierten CSV-Format einlesen. Sollten Fehler auftreten, ist wie im Interface beschrieben eine java.io.IOException zu werfen.


----------



## BC_1992 (31. Aug 2015)

Ich habe es mit equals probiert:

```
if ((line=scan.nextLine()).equalsIgnoreCase("date;open;high;low;close"))
                 throw new IOException();
```


----------



## Dompteur (31. Aug 2015)

IOException sollte doch geworfen, wenn es ungleich ist und nicht, wenn es gleich ist.


----------



## BC_1992 (31. Aug 2015)

Stimmt dann so oder? :

```
if (!(line=scan.nextLine()).equalsIgnoreCase("date;open;high;low;close"))
                 throw new IOException();
```


----------



## lant (31. Aug 2015)

da muss noch ein ! - Zeichen hin, vor die zweite Klammer-auf. sonst wird immer eine Exception geworfen wenn der Kopf dem entspricht


----------



## lant (31. Aug 2015)

sorry ja genau


----------



## BC_1992 (31. Aug 2015)

Trotzdem danke - Sitze nur noch an diesen Fehlern und es scheint als ob niemand helfen kann


----------



## BC_1992 (31. Aug 2015)

Es wäre wirklich nett, wenn sich jemand erbarmen würde und mir hier hilft.


----------



## Tobse (31. Aug 2015)

Wir befinden uns in Phase 3: http://www.java-forum.org/thema/die...schleichen-von-loesungen-fuer-aufgaben.63088/


----------



## BC_1992 (31. Aug 2015)

Bei allem Respekt aber ich habe einen Fehler und weiß nicht wie ich ihn beheben soll. Ich will nicht das jemand für mich die ganze Aufgabe löst sondern mir erklärte worin genau der Fehler liegt und wie ich ihn behebe.

Ist ein Java Forum nicht dafür da, dass man sich gegenseitig bei Problemen hilft?


----------



## lant (31. Aug 2015)

wenn man die toString Methode bei dem Scanner aufruft bekommt man doch die Speicheradresse des Scanners, oder liege ich da falsch?
Dann würde der Rest auch nicht funktionieren


----------



## Tobse (31. Aug 2015)

BC_1992 hat gesagt.:


> Ist ein Java Forum nicht dafür da, dass man sich gegenseitig bei Problemen hilft?


Ich nutze es als einen Platz für die Hilfe zur Selbsthilfe; von deinem Lösungsansatz lässt sich momentan nichts sehen: du hast dir anscheinend nicht einmal den StackTrace der Exception angeschaut.

Diese Aufgabe ist ja für die Uni, oder? Das bedeutet ja, dass die Tests, die der Uni-Server gegen deinen Code macht, auch in der Aufgabe stehen (oder gleichwertige Tests). Hast du es denn damit mal selbst probiert und geschaut, wo genau der Fehler auftritt?
Wenn du das weisst: verfolge deinen Code zurück mit dem Ziel: wie kommt es dazu? Und dabei wirst du auf ungereimtheiten stoßen, welche dir dann zeigen, was du an deinem Code ändern musst.

Wenn wir dir die Lösung einfach so geben, entgeht dir ein wichtiger Lernerfolg.



lant hat gesagt.:


> wenn man die toString Methode bei dem Scanner aufruft bekommt man doch die Speicheradresse des Scanners, oder liege ich da falsch?
> Dann würde der Rest auch nicht funktionieren


Der String, den das liefert enthält unter anderem die Addresse, richtig.


----------



## BC_1992 (1. Sep 2015)

Das Problem ist, es wird nicht angezeigt an welcher Stelle die Exception geworfen wird. Nur das eine geworfen wird.


----------



## lant (1. Sep 2015)

Nutz doch die Debug Funktion deiner Entwicklungsumgebung, wenn du ein Breakpoint vorher setzt kannst du von da an jeden Schritt der gemacht wird mitverfolgen und dadurch sehen wo sie geworfen wird


----------



## BC_1992 (1. Sep 2015)

Okay, dafür müsste ich erstmal eine main-Methode schreiben oder?


----------



## Joose (1. Sep 2015)

Ohne main-Methode lässt sich ein Java Programm nicht starten


----------



## BC_1992 (1. Sep 2015)

Okay dann probiere ich das jetzt . Danke für den Tipp


----------



## Dompteur (1. Sep 2015)

Möglicherweise wird dir der Einarbeitungsaufwand für dein konkretes Problem zu groß sein.

Aber normalerweise löst man so etwas durch einen Satz von Testfällen. Statt einer main-Methode erstellt man da also JUnit Tests.


----------



## lant (1. Sep 2015)

kommst du soweit jetzt klar oder brauchst du noch Hilfe?


----------



## BC_1992 (1. Sep 2015)

Ich probiere erstmal die Main Methode zu machen und dann herauszufinden wo der Fehler herkommt. Ich schreib nochmal ins Forum wenn ich nicht mehr weiter komme


----------



## BC_1992 (1. Sep 2015)

Okay ich hab es nicht hingekriegt..


----------



## lant (1. Sep 2015)

Zeig mal wie es jetzt aussieht und die Fehlermeldungen


----------



## BC_1992 (1. Sep 2015)

Nur die Missglückte MainMethode oder alles?


----------



## lant (1. Sep 2015)

Zeig mal die Main und die csvshareimporter


----------



## BC_1992 (1. Sep 2015)

Okay

```
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Scanner;

public class CSVShareImporter implements ShareImporter {
     private Scanner scan;
    private Scanner innerScan;

    @Override
     public Collection<Share> load(InputStream is) throws IOException {
      
             scan = new Scanner(is);
             Collection<Share> shares = new ArrayList<Share>();
             String line="date;open;high;low;close";
                
           

             if (!(line=scan.nextLine()).equalsIgnoreCase("date;open;high;low;close")) //scanner nimmt die erste Zeile und schaut, ob sie richtis ist
                 throw new IOException();
            
             String shareInput = scan.toString(); //restlicher Text wird zu einem langen String gemacht
             String[] splitShareInput = shareInput.split(("SHARE;")); //Langes String zu Array, wird immer an "SHARE" geteilt
             for(String s : splitShareInput){
               
                     String name;
                     innerScan = new Scanner(s);
                     line = innerScan.nextLine();
                     name = line.split(";")[0]; //Die Zeile wird aufgesplittet und der erste Wert uebernommen
                     ArrayList<Dataset> set = new ArrayList<Dataset>();
                     while ((line=scan.nextLine()) != null) {//solange das jeweilige Array nicht zu Ende ist
                             Calendar date = Calendar.getInstance(); //neuen Calendar erstellen
                             String[] splitLine = line.split(";"); //schon wieder Array
                           
                             date.set(Integer.valueOf(splitLine[0].split(".")[2]), //Datum wird uebergeben, aufgesplittet und die jeweiligen Werte verwendete
                                             Integer.valueOf(splitLine[0].split(".")[1]),
                                             Integer.valueOf(splitLine[0].split(".")[0]));
                             Dataset dataset = new Dataset(date, Integer.parseInt(splitLine[1]),
                                                             Integer.parseInt(splitLine[2]),
                                                             Integer.parseInt(splitLine[3]),
                                                             Integer.parseInt(splitLine[4]));
                             set.add(dataset);
                     }
                     Share share = new Share(name, set);
                     shares.add(share);
             }
            
              
             return shares;
    }
             public static void main(String[]args) throws IOException{
                 String csv = "date;open;high;low;close";
                 InputStream is = new ByteArrayInputStream(csv.getBytes("UTF-8"));
                 CSVShareImporter imp = new CSVShareImporter();
                 System.out.println(imp.load(is));
                
                
             }

   
   
}
```


----------



## lant (1. Sep 2015)

also die main funktioniert eigentlich. Das erste Problem ist, dass du mit scan.nextLine nicht überprüfen kannst, ob der Stream zu ende ist ohne eine Exception  geworfen zu bekommen. Also müsstest du die Überprüfung in der Schleife mit hasNext() machen


----------



## BC_1992 (1. Sep 2015)

Aber sobald ich irgendwo hasNext() schreibe, zeigt es überall Fehler an


----------



## lant (1. Sep 2015)

wenn du es nicht machst fliegen dir Exception um die Ohren weil der Stream zu ende ist und wenn da Fehler auftauchen, dann musst du das akzeptieren und diese dann beseitigen in dem du verstehst wodurch sie auftreten


----------



## BC_1992 (1. Sep 2015)

Hm okay. Dann schau ich mal wie ich es mache.


----------



## lant (1. Sep 2015)

Wenn du das machen willst, dass du da den ganzen Stream als einen String schreiben willst solltest du das  verwenden und nicht toString:

```
String shareInput = "";
while(scan.hasNext()){
shareInput += scan.nextLine();
}
```


----------



## lant (1. Sep 2015)

die zweite while schleife wäre dann aber so nicht mehr zu gebrauchen, weil dann alles in einer Zeile stehen würde. Dann müsste man da noch einen Zeilenumbruch mit einbauen bei dem einlesen als ein String, also so ungefähr:

```
while(scan.hasNext()){
shareInput += scan.nextLine() + "\n";
}
```


----------



## BC_1992 (1. Sep 2015)

Okay danke


----------



## lant (1. Sep 2015)

dann musst du bei deiner Schleife wo du stehen hast:
	
	
	
	





```
while (line=scan.nextLine())!=null)
```
da musst du das so verändern:
	
	
	
	





```
while (innerScan.hasNext()){
line = innerScan.nextLine();
}
```
so dürfte das bis dahin funktionieren


----------



## Dompteur (1. Sep 2015)

Was macht das eigentlich für einen Sinn, einen 2. Scanner zu verwenden ?

So könnte man das mit einem Scanner machen: 

```
if ( !scan.hasNext() ) {
            throw new IOException();
        }
 
        //scanner nimmt die erste Zeile und schaut, ob sie richtis ist
        if (!(scan.nextLine()).equalsIgnoreCase(headerLine)) {
            throw new IOException();
        }
 
 
        // Iteration über die Datenzeilen:
        while ( scan.hasNext() ) {
            String line = scan.nextLine();
 
            // hier die Daten für Dataset aus dem String line auslesen
            // dann ein Share Objekt anlegen.
          
            shares.add(share);
        }
```
 
Musst du nicht alle Kurse der gleichen Aktie zusammenfassen ?
Die Datenstruktur läßt mich das vermuten.
Shares besteht ja aus einem Namen und einer Liste von Datasets. Ein Dataset ist wiederum eine Klasse mit Datum und 4 Werten.
Wenn also "Adidas" 2x vorkommt, dann würde ich intuitiv erwarten, dass es nur einen Eintrag dafür in Shares gibt und dieser die beiden Kurse enthält.


----------

