# Hilfe bei einer Aufgabe - Objekte speichern und auf Methode zugreifen?



## N00b92 (21. Jul 2014)

Hallo liebe User,

ich studiere IT im 2. Semester.
Bald stehen die Klausuren an und ich versuche die alten Klausuren zu lösen.
Leider steht mir keine Musterlösung zur Verfügung, deswegen hoffe ich hier auf eine kleine Hilfestellung.

Zur Aufgabe.:
Ich bin mir sicher, dass ich die ersten Aufgaben richtig gelöst habe, deswegen poste ich sie hier nicht.

Die weitere Aufgaben.:

Schreiben Sie das Hauptprogramm main mit den folgenden Aktionen:
- ArrayList "warenList" für Ware-Objekte anlegen.
- Speichern 10 Objekte vom Typ Ware mit Name "Apfel" und Preis 2,99, in der
warenList

-------------------Ab hier komme ich wieder nicht weiter---------------------

- Speichern 20 Objekte vom Typ WareR mit Name "Birne", Preis 3,79 und
Preisreduzierung 0,30 in der warenList
- Setzen des Attributs reduziert von den angelegten WareR-Objekten als true
- Anzeigen des gesamten Warenbestands der warenliste auf dem Bildschirm
mittels Iterator und unter Benutzung der Methode anzeigen().


Mein Code.:

MAIN


```
import java.util.*;

public class Hauptprogramm {

    public static void main(String[] args) {

        ArrayList<Ware> warenListe = new ArrayList<Ware>();

        for (int i = 0; i < 10; i++) {

            warenListe.add(new Ware("Apfel", 2.99));

    }
  }
}
```

Klasse Ware



```
public class Ware {
    
    String name;
    double preis;
    
    Ware(String warenName, double warenPreis){
        this.name = warenName;
        this.preis = warenPreis;
        
    }
    
    void anzeigen(){
        System.out.println("/n Name: "+this.name+"/n Preis: "+this.preis);
    }

}
```

Klasse WareR


```
public class WareR extends Ware{
    
    double reduzierung;
    boolean reduziert;

    public WareR(String warenName, double warenPreis, double preisReduzierung) {
        super(warenName, warenPreis);
        
        this.reduziert=false;
        
        
        
    }
    
    public void setReduziertAls(boolean value){
       
        this.reduziert=value;
        
    }
    
    public void anzeigen(){
        
        double value;
        
        if(this.reduziert==false){
            
            System.out.println("/n Name: "+name+"/n Preis: "+preis);
            
        }
        
        else{
            
            value = preis - this.reduzierung;
            System.out.println("/n"+name+" reduziert auf "+value+" von "+preis);
            
        }

    
    
    }
  
    
}
```


Meine Fragen sind zu dieser Aufgaben, denn ab hier komme ich nicht weiter.:
- Speichern 20 Objekte vom Typ WareR mit Name "Birne", Preis 3,79 und
Preisreduzierung 0,30 in der warenList
- Setzen des Attributs reduziert von den angelegten WareR-Objekten als true
- Anzeigen des gesamten Warenbestands der warenliste auf dem Bildschirm
mittels Iterator und unter Benutzung der Methode anzeigen().

1. und 2. Spiegelstrich:

Hab mir gedacht
WareR array[] = new WareR[10];
Die 20 Objekte in dem Array speichern und durch
array_.setReduziertAls(true);

Aber das haut nicht hin, ich weiss echt nicht weiter und hoffe auf ne kleine Hilfestellung. :lol:

Lg :idea:_


----------



## Flown (22. Jul 2014)

Also du hast schon fast alles richtig meiner Meinung nach. 
Es sind ein paar Kleinigkeiten die ich ändern würde.

- Beim Konstruktor der Subklasse WareR übergibt man Name, Preis, Preisreduktion:
Diese sollten gespeichert werden (hast du auch schon richtig gemacht mit dem super-Konstruktor), aber die Preisreduktion muss noch gespeichert werden.

- Den Boolean reduziert setzt man nur in der setter-Methode.
Weil es kann ja sein, dass man schon für zukünftige Aktionen die Preisreduktion eingibt, aber noch nicht freischaltet (z.B.)

- In der Methode anzeigen, braucht man nicht nocheinmal die Anzeige für die Superklasse machen, da sie dort schon implementiert ist, d.h. wenn das Produkt nicht preisreduziert ist, dann kann man das mit einem 
	
	
	
	





```
super.anzeigen();
```
 lösen.

Jetzt zu deinen "Problemen". Da du alles schon dortstehen hast, geb ich dir nur einen Denkanstoß.

20 Objekte können, wie du bereits es mit den Äpfel gemacht hast, in einer weiteren Schleife hinzugefügt werden. Doch in der Schleife fügst du nicht gleich das Objekt der Collection hinzu sondern speicherst es in einer Variable. Darauf führst du dein Attribut setzen aus und fügst es dann in die Collection hinzu.

Problem 2:
Iteratoren werden so verwendet:


```
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
Iterator<Integer> iter = list.iterator();
while(iter.hasNext()) {
	Integer i = iter.next();
	System.out.println(i);
}
```

Java hat auch netten Syntactic Sugar und man kann Iteratoren mit for-each loops maskieren (was ihr wahrscheinlich nicht machen dürft - aber gut zu wissen):


```
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for(Integer i : list) {
	System.out.println(i);
}
```

Mehr Fragen? Immer her damit!


----------



## N00b92 (22. Jul 2014)

Super, danke dir!
Habe geschafft! (Y)

Eine kleine Frage habe ich da noch.
Nehmen wir mal an, ich möchte die gespeicherten Objekte in eine .txt Datei schreiben.

Die kann ich hiermit machen.:






```
RandomAccessFile racf = new RandomAccessFile("Datei", "rw"); // Werte in die Datei schreiben
racf.writeWare(warenListe);
```

Nun habe ich alle Objekte in die Datei geschrieben.
Woher weiss ich jetzt wie groß ein Objekt ist?


Bzw. anders Formuliert, wie kann ich jetzt z.b. Objekt 4 oder Objekt 3 oder Objekt n ... einlesen?
Ich weiss das es so gehen müsste.


```
racf.seek( x ); // Positionszeiger auf das x-te Byte setzen 
Ware ein = racf.readWare( ); // Ware-Objekt lesen
racf.close( ); // Datei schließen racf.close( );
```

Woher weiss ich jetzt wie gross ein Objekt ist bzw. was muss ich dann für x wählen um z.b. Objekt 5 einlesen zu können.

Danke im voraus und LG :toll:


----------



## Flown (22. Jul 2014)

Also selektives speichern/laden ist immer so eine Sache. Es kommt darauf an wie du deine Objekte speichern willst (CSV, XML, ...).
Aber die beste Lösung wäre für solch kleine Sachen eine CSV-Datei, wo pro Zeile ein Objekt liegt. Oder du serialisiert die Objekte jeweils in ein eigenes File. 

Soetwas in der Art:



Spoiler: BasketApplication.java





```
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class BasketApplication {
	
	public static final Path FILE_PATH = Paths.get("Warenliste.txt");

	public static void main(String[] args) {
		new BasketApplication();
	}

	public BasketApplication() {
		List<Article> itemList;
		
		if(Files.exists(FILE_PATH)) {
			itemList = readFromFile(FILE_PATH);
			System.out.println("Read from file!");
		}
		else {
			itemList = populateData();
			System.out.println("Generated data!");
			writeToFile(FILE_PATH, itemList);
			System.out.println("Wrote generated data to file!");
		}
		
		Iterator<Article> iter = itemList.iterator();
		while(iter.hasNext()) {
			Article ware = iter.next();
			ware.print();
		}
	}

	private List<Article> populateData() {
		List<Article> warenListe = new ArrayList<>();
		
		for (int i = 0; i < 10; i++) {
			warenListe.add(new Article("Apple", 2.99));
		}
		for (int i = 0; i < 20; i++) {
			ReducedArticle birne = new ReducedArticle("Pear", 3.79, 0.3);
			birne.setReduced(true);
			warenListe.add(birne);
		}
		return warenListe;
	}
	
	public void writeToFile(Path path, List<Article> bucket) {
		try {
			BufferedWriter writer = Files.newBufferedWriter(path);
			for(Article article : bucket) {
				writer.write(article.getSerializeString());
				writer.write("\n");
			}
			writer.flush();
			writer.close();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public List<Article> readFromFile(Path path) {
		List<Article> bucket = new ArrayList<>();
		try {
			
			List<String> lines = Files.readAllLines(path);
			for(String line : lines) {
				String[] values = line.split(",");
				// Article
				if(values.length == 2) {
					String name = values[0];
					double price = Double.parseDouble(values[1]);
					bucket.add(new Article(name, price));
				}
				// ReducedArticle
				else if(values.length == 4) {
					String name = values[0];
					double price = Double.parseDouble(values[1]);
					double priceCutting = Double.parseDouble(values[2]);
					boolean isReduced = Boolean.parseBoolean(values[3]);
					ReducedArticle rArticle = new ReducedArticle(name, price, priceCutting);
					rArticle.setReduced(isReduced);
					bucket.add(rArticle);
				}
				else {
					throw new IllegalArgumentException("Serialized type unknown!");
				}
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		
		return bucket;
	}

	class Article {
		protected String name;
		protected double price;

		public Article(String name, double price) {
			this.name = name;
			this.price = price;
		}

		public void print() {
			System.out.println("name: " + name + "; price: " + price);
		}
		
		public String getSerializeString() {
			return name + "," + price;
		}
	}

	class ReducedArticle extends Article {
		protected double priceCutting;
		protected boolean isReduced;

		public ReducedArticle(String name, double price, double priceCutting) {
			super(name, price);
			this.priceCutting = priceCutting;
		}

		public void setReduced(boolean isReduced) {
			this.isReduced = isReduced;
		}

		@Override
		public void print() {
			if (isReduced) {
				System.out.println(name + " reduced to " + (price-priceCutting) + " from " + price);
			}
			else {
				super.print();
			}
		}
		
		@Override
		public String getSerializeString() {
			return name + "," + price + "," + priceCutting + "," + isReduced;
		}
	}
}
```




Kleiner Tipp am Rande: fang an englische Bezeichnungen und Programme zu schreiben.


----------

