Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
hallo,
kann einer von euch mir einen link schicken oder mir erklären wie ich anhand von properties file objekte erstellen kann? mein code liest meinen properties file und gibt ihn mir in der console aus, jedoch kann ich auf die elemente des files mit methoden nicht zu greifen.
ich habe jetzt gerade Probleme zu verstehen, was genau dein Problem ist. Ein Properties-File ist ja nur sowas wie ein Config-File. Und aus hinterlegten Werten möchtest Du nun Objekte erstellen? Wenn du neue Instanzen erstellen möchtest, dann müsstest Du dir mal den Bereich Classloader und so ansehen. Das kann aber je nach Anforderung recht aufwendig werden. Der Code kann dann wie folgt aussehen:
Java:
Class<?> clazz =Class.forName(className);
Constructor<?> ctor = clazz.getConstructor(String.class); // KOnstructor mit einem String als Argument
Object object = ctor.newInstance(newObject[]{ ctorArgument }); // Aufruf Konstruktor mit ctorArgument als Argument.
Oder willst Du nur einfach auf die Properties aus dem File zugreifen?
Dazu brauchst Du nur eine Instanz von Properties und in die lädst Du dein properties file:
Java:
Properties properties = new Properties();
BufferedInputStream stream = new BufferedInputStream(new FileInputStream("beispiel.properties"));
properties.load(stream);
stream.close();
String sprache = properties.getProperty("lang"); // Speichert den Wert von lang aus dem properties file beispiel.properties in Variable sprache
{
try {
Properties kundenDaten = new Properties();
kundenDaten.load(new FileInputStream("C:/Users/admin/workspace/Software/unsere2.txt"));
String[] namen = kundenDaten.getProperty("nachname").split(";");
String[] vornamen = kundenDaten.getProperty("vorname").split(";");
String[] datum = kundenDaten.getProperty("gebDatum").split(";");
String[] id = kundenDaten.getProperty("karteID").split(";");
for (int i = 0; i < namen.length; i++) {
Karte karte = new Karte(namen[i], vornamen[i], datum[i], id[i]);
System.out.println(karte);
}
} catch (FileNotFoundException ef) {
log.info("Datei nicht vorhanden\n" + ef);
} catch (IOException eg) {
log.info("Konnte nicht gelesen werden\n" + eg);
}
}
so sieht mein Code aus. In der for-Schleife werden ja die Objekte erstellt oder nicht? Aber so bald ich mit den Methoden auf das Objekt zu greifen möchte erkennt das Programm die erstellten Objekte nicht.
Ja du erstellst in der for-Schleife Objekte vom Typ Karte.
Diese Objekte gibst du auf der Konsole aus und weiter machst du damit nichts -> da keine Referenz mehr darauf besteht wird der GC sie aufräumen um den Speicher freizumachen.
Mit welchen Methoden? Auf welches Objekte willst du zugreifen?
Hier brauchen wir schon etwas mehr Code. Am besten von der Stelle wo der Fehler auftaucht!
in der for Schleife erstellst Du eine lokale Variable karte, die Du erzeugst und ausgibst. Da du diese aber nicht weiter referenzierst, ist die nach dem println Aufruf direkt weg.
Du könntest also eine Collection von Karten aufbauen. Also z.B. könntest Du in Deiner Klasse eine ArrayList<Karte> definieren (ArrayList<Karte> karten = new ArrayList<Karte>() und dann in der for schleife die karte sichern (karten.add(karte) Dadurch hättest Du dann alle Karten in der ArrayList verfügbar.
Also genau wie angenommen: Du erstellst eine lokale Variable innerhalb der for Schleife. Diese Variable gibt es nur innerhalb der for Schleife und nicht ausserhalb. Damit Du auf die Instanzen von Karte weiter zugreifen kannst, musst Du die Referenz irgendwo merken. Einen kleinen Vorschlag habe ich ja bereits unterbreitet.
Gut wie @kneitzel schon sagte. Du erstellst in deiner for-Schleife nur lokale Objekte welche außerhalb der Schleife nicht verfügbar sind.
Du musst sie wie schon erwähnt in eine Liste geben oder ähnliches.
Zu deinen Code: Probiere ihn etwas besser zu strukturieren dadurch wirst du dir auch in Zukunft leichter tun sobald er umfangreicher wird
Deine Funktionalität um aus der Datei Objekte zu erstellen steht einfach so im Initialisierer -> besserer Ort wäre der Konstruktor
Mittem im Konstruktor steht eine andere Klassendefinition -> auslaggern oder aber wenigstens nach dem Konstruktor anstatt mittendrin
Und versuche die "Redundanzen" zu vermeiden. Du speicherst erst alles in Arrays und ezeugts anhand diese dann deine Objekte. Versuche doch die Objekte direkt zu erstellen. Das ist ja grad der Vorteil an der OOP, dass uns sowas wie:
Java:
String[] namen
String[] vornamen
String[] datum
String[] id
erspart bleibt. Schöner wäre z.B. eine ArrayList aus Karten.
Gleiches Problem in grün. Du hast karten (die ArrayList) jetzt lokal im Konstruktor deklariert. Danach ist sie weg. Du solltest sie als Instanzvariable definieren und eine getter-Methode dafuer machen und dann kannst du über deine Karten iterieren.
ich komme wirklich nicht weiter. ich habe alles probiert. wo müsste ich denn die for-schleife definieren, damit es funktioniert. habe es probiert außerhalb des Konstruktors also direkt in der klasse zu machen. da traten viel mehr fehler auf.
Also ich sehe mehrere Dinge:
a) public Karte karte =new Karte(nachname, vorname, gebDatum, karteID);
Hier erstellst Du eine neue Karte, die in karte gespeichert wird. Soweit so gut. Aber die Initialisierung läuft direkt, wenn die Instanz erzeugt wird, noch vor dem Konstruktor. Damit erzeugst Du eine "leere" Karte, da nachname, vorname, gebDatum und KarteID leer sind.
b) In Deinem Konstruktor definierst Du viele lokale Variablen, die Du im Konstruktor füllst. Da die Variablen aber lokale sind, sind die nach Beendigung des Konstruktors auch wieder weg.
Desweiteren verstehe ich die ganze Logik nicht. Du hast eine Klasse "Kartenverwaltung". Darunter verstehe ich die Verwaltung von mehreren Karten. Aber dann definierst Du einzelne Werte, die doch eine Karte sind, oder nicht?
Eine Klasse Karte hast Du ja - nur was ist da dann drin?
Ich würde in der Kartenverwaltung eine Collection von Karten erwarten oder so. Also das, was Du im Konstruktor dann auch definierst:
ArrayList<Karte> karten =new ArrayList<Karte>();
Also schmeiss die nachname, vorname, gebDatum und karteID raus. Ebenso die Karte. Statt dessen definierst Du ArrayList<Karte> karten = new ArrayList<Karte>(); ausserhalb des Konstruktors. (Also die Zeile im Konstruktor löschen/ausschneiden und dafür ausserhalb des Konstruktors einfügen.)
Und schon hast Du da dein ArrayList von Karten - und Du musst dann nur noch die Funktionen für Zugriffe bauen, die Du so brauchst.
definierst Du ArrayList<Karte> karten = new ArrayList<Karte>(); ausserhalb des Konstruktors. (Also die Zeile im Konstruktor löschen/ausschneiden und dafür ausserhalb des Konstruktors einfügen.)
Das ist mal der erste Schritt den du unbedingt brauchst. Damit sollte es erst mal funktionieren. Den Rest der Vorschläge kannst du dann anschliessend umsetzen.
definierst Du ArrayList<Karte> karten = new ArrayList<Karte>(); ausserhalb des Konstruktors. (Also die Zeile im Konstruktor löschen/ausschneiden und dafür ausserhalb des Konstruktors einfügen.)
Deine Kartenverwaltung kv enthält ja eine Liste von Karten. Du musst dir natürlich jetzt ein Element aus dieser Liste holen und dann was damit machen. Deshalb solltest du auch die "karte" nach der ich oben gefragt hatte löschen damit es keine Verwechslungsmöglichkeiten gibt !!!
Daher sollte man Müll aus einer Klasse direkt rausschmeissen. Hatte ja schon geschrieben, dass diese Dinge da nichts verloren haben.
Aber schau einfach einmal, wo du die KarteN (!!!) speicherst und wo du etwas liest. Oder Vergleich mit der realen Welt: Wenn Du etwas ins Wohnzimmer legst wirst Du es im Schlafzimmer nicht finden können.
JStein52: Darauf greift er ja wohl nicht zu sondern seine Klasse ist auch noch eine Karte und hat die Instanzvariablen und getter/setter ... Die müssen auch alle endlich raus. Und dann muss er Methoden für Zugriffe auf die Arraylist schreiben denn ohne Kapselung ist das auch nichts richtiges.
Doch, genau da greift er drauf zu Seine Klasse ist übrigens keine Karte sondern sie enthielt noch eine Karte, die muss weg mitsamt allen Methoden da drauf. Statt dessen braucht er z.B. eine getKarteByID die ihm aus der Liste von Karten die passende raussucht. Und aus der wiederum kann er sich die anderen Attribute rausholen.
also leute als erstes möchte ich mich für all eure hilfe und mühen bedanken. "karte" ist ein objekt wo ich die daten speichere. sie enthält die konstruktor als beschreibt wie karte aufgebaut ist(name, nachname,id...). für jeden kunden eine karte. in der arraylist möchte ich diese karte speichern. damit ich nicht auf jede einzelnes objekt(karte) zu greiffen muss, d.h. ich müsste dann für jeden kunden eine eigene if-anweisung erstellen. so hatte es geklappt, aber wenn man überelgt, dass man für 100 oder 1000 kunden eine if-anweisung erstellen soll....deswegen wollte ich alle kunden in einer arrayliste speichern
Irgendwie ist das ein bisschen verquer. In karte kannst du doch nur einen einzigen Kunden speichern ???
Welchen von den tausend Kunden speicherst du denn in Karte ? Irgendwie ist dein Konzept falsch. Deine Kunden stehen doch in der Liste von Karten alle drinnen ???
@kneitzel Du hattest übrigens recht, seine Kartenverwaltung ist auch noch eine Karte weil sie alle Attribute einer Karte ebenfalls nochmal enthält. Plus eine Instanz von Karte plus eine Liste von Karten. Ein bisschen viel Karten.
Properties kundenDaten = new Properties();
kundenDaten.load(new FileInputStream("C:/Users/admin/workspace/Software/unsere2.txt"));
String[] nachnamen = kundenDaten.getProperty("nachname").split(";");
String[] vornamen = kundenDaten.getProperty("vorname").split(";");
String[] gebDatum = kundenDaten.getProperty("gebDatum").split(";");
String[] karteID = kundenDaten.getProperty("karteID").split(";");
for (int i = 0; i < nachnamen.length; i++) {
Karte karte = new Karte(nachnamen[i], vornamen[i], gebDatum[i], karteID[i]);
karten.add(karte);
System.out.println(karte);
}
hier werden ja die daten geladen. aus den daten werden pro kunde eine karte erstellt und diese objekte (karte) in die arrayliste hinzugefügt (alles in der for-schleife). auch gibt er mir alle kunden geordnet in der console aus. jedoch kann das programm (also terminal) auf diese liste nicht zugreiffen
Ja der Teil ist ja auch in Ordnung. Du musst dir nun passende Zugriffsmethoden auf diese Liste bzw. auf Karten aus dieser Liste machen. z.B. eine getKarteByID oder eine getKarten die dir die Liste zurückgibt so dass du darüber iterieren kannst usw. Was du halt in deiner Anwendung brauchst.
es existieren getter/setter für kartenverwaltung. habe auch dieses objekt "karte" aus kartenverwaltung entfernt. habe auch 'import logic.karte' aus 'terminal' auskommentiert. so dass 'termina'l die klasse 'karte' gar nicht erkennt und nur noch auf die getter/setter von kartenverwaltung zugreiffen muss, jedoch bringt das alles irgendwie auch nichts.
Wichtige Frage: Hast Du das Kernproblem soweit verstanden? Wenn nicht, dann ignoriere den folgenden Text erst einmal und melde dich noch einmal! Dann würde dir einer von uns die Klasse kurz anpassen, so dass sie erst einmal korrekt ist.
Jetzt sind wir ggf. bei den Zugriffen auf die Karten. Und da wäre es ja super, wenn man zügig von einer ID zu der Karte kommen könnte. Oder von dem Namen zu der Karte.
So gibt es sogenannte Maps. Diese Speichern immer Key Value Paare. Über den Key kann man den Wert schnell ermitteln. So könnte man die Karten statt in einer ArrayList in HashMaps speichern. So wäre eine HashMap denkbar, die KartenId und Karte speichert. Dann kann man schnell über die KartenID auf die Karte zugreifen.
Hier aber gleich zwei Probleme, die man auch bedenken muss:
a) Pro Key kann nur ein Wert angespeichert werden. Also wenn man Geburtstag -> Karte speichern würde, dann hätte man Probleme, wenn auf zwei Karten das gleiche Geburtsdatum ist.
b) Änderungen auf einer Karte ändern nicht automatisch die Hashmap. Also ich habe die Karte von Hr. Maier in der HashMap. Dann habe ich den Key "Hr. Maier" -> Karte von Hr. Maier. Nun ändere ich den Namen auf der Karte von Hr. Maier zu Hr. Schmidt. Dann habe ich in der Hashmap "Hr. Maier" -> Karte von Hr. Schmidt (ehemals Hr. Maier). Die kann ggf. problematisch sein!
Ok, kannst Du bitte einmal die beiden aktuellen Klassen komplett posten? Ich würde diese dann einmal für Dich anpassen (so mir niemand zuvor kommt). Dann verstehst Du evtl. das, was wir meinen, besser. Und meinen Post von oben ignorierst Du erst einmal bis wir das abgeschlossen haben.
Während @kneitzel arbeitet () mal zwischendurch eine Frage: was ist eigentlich die Anwendung hinter dem ganzen ? Ändern sich diese Kundendaten innerhalb deiner Anwendung ? Werden diese Änderungen dann wieder in der Datei gespeichert die du da einliest ? Ist diese Datei vorgegeben ? Hast du dir mal überlegt deine Kunden evtl. in einer kleinen Datenbank (SQLLite ?) abzulegen ?
also wir probieren als eine gruppe eine kleine Schrankverwaltung zur erstellen. einfach schränke öffnen und schließen. anzeigen wie viele schränke frei/besetzt sind. dieser teil der aufgabe ist es einfach nur, dass im terminal angezeigt werden solche welcher kunde welche schranknr hat. also später wird bestimmt die Schranknr sich wechseln, aber ich sollte halt jetzt nur mal diesen teil des programmes schreiben
Also die aktuellen Versionen sind zwar noch nicht gepostet worden, aber ich habe jetzt einmal schnell eine neue Version gebaut. Die Klasse Karte war noch nirgends, aber Kartenverwaltung hatte ja alles, so dass ich das einfach kopiert habe und den Konstruktor erzeugt habe.
Code:
package logic;
public class Karte {
private String karteID;
private String gebDatum;
private String nachname;
private String vorname;
public String getKarteID() {
return karteID;
}
public void setKarteID(String karteID) {
this.karteID = karteID;
}
public String getGebDatum() {
return gebDatum;
}
public void setGebDatum(String gebDatum) {
this.gebDatum = gebDatum;
}
public String getNachname() {
return nachname;
}
public void setNachname(String nachname) {
this.nachname = nachname;
}
public String getVorname() {
return vorname;
}
public void setVorname(String vorname) {
this.vorname = vorname;
}
public Karte(String nachname, String vorname, String gebDatum, String karteID) {
this.nachname = nachname;
this.vorname = vorname;
this.gebDatum = gebDatum;
this.karteID = karteID;
}
}
Code:
package logic;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import utils.LogFactory;
public class Kartenverwaltung {
public static Logger log = LogFactory.createLogFor(Kartenverwaltung.class);
private ArrayList<Karte> karten = new ArrayList<Karte>();
public Kartenverwaltung(){
try {
Properties kundenDaten = new Properties();
kundenDaten.load(new FileInputStream("C:/Users/admin/workspace/Software/unsere2.txt"));
String[] nachnamen = kundenDaten.getProperty("nachname").split(";");
String[] vornamen = kundenDaten.getProperty("vorname").split(";");
String[] gebDatum = kundenDaten.getProperty("gebDatum").split(";");
String[] karteID = kundenDaten.getProperty("karteID").split(";");
for (int i = 0; i < nachnamen.length; i++) {
Karte karte = new Karte(nachnamen[i], vornamen[i], gebDatum[i], karteID[i]);
karten.add(karte);
System.out.println(karte);
}
// log.info("Kunden: " + kundenDaten);
} catch (FileNotFoundException ef) {
log.info("Datei nicht vorhanden\n" + ef);
} catch (IOException eg) {
log.info("Konnte nicht gelesen werden\n" + eg);
}
}
/**
* Gibt die Karte mit der kartenId zurück.
* @param kartenId Id der Karte.
* @return Die gefundene Karte oder null, falls die passende Karte nicht gefunden wurde.
*/
public Karte getKarteById(String kartenId) {
for (Karte karte: karten) {
if (karte.getKarteID().equals(kartenId)) {
return karte;
}
}
return null;
}
}
Anmerkungen:
- Ich bin der Meinung, dass jedes Element, das nicht private ist, per JavaDoc dokumentiert werden sollte. Wie das aussehen kann, habe ich an der KartenVerwaltung.getKarteById gezeigt. (Kommentar auf Deutsch - war sehr gewöhnungsbedürftig. Ich entwickle alles eigentlich in Englisch, denn so ist es einheitlich. Die Funktionen und Klassen sind ja schon Englisch und ein Mischmasch sieht nicht so gut aus. Daher auch getKarteById. Also Denglisch ...
- Bei der Klasse Karte könnte noch toString und hashCode überschrieben werden um vollständig zu sein.
- Ich habe die Klasse Kartenverwaltung zu KartenVerwaltung gemacht. Bei zusammengesetzen Wörtern wird jedes neue Wort groß geschrieben. Das macht es einfacher zu lesen.
- Ich bin bei der ArrayList geblieben. Daher die Suche über eine foreach Schleife. Eine Map kann ja als nächste Änderung selbst gebaut werden.
- Welches Logging wird hier verwendet? Ist das etwas selbst gestricktes? Namespace util sieht etwas danach aus. Beim Logging würde ich entweder java.util.logging nutzen (http://openbook.rheinwerk-verlag.de/java7/1507_20_001.html) oder wenn mehr benötigt wird das log4j, was aber dann eine weitere Abhängigkeit einfügt. Eine Exception so anzuhängen bringt meines Wissens nicht alles Informationen mit. Aber die wollen wir schon haben. Die Logging-Frameworks können sich darum kümmern - die Funktionen zum loggen nehmen oft die Exception als weiteren Parameter. Evtl. ist das ja auch bei Deiner util.Logging Lösung so?
- Namespace namen - hier sollten Namen gewählt werden, die eindeutig sind. Dazu wurde das DNS System zweckentfremdet. Ich nutze daher gerne de.kneitzel.* um eindeutige Namespaces zu haben. Wenn keine eigene Domain vorhanden ist, dann ist eine Email-Adresse oft gut. Also wenn Du Irgend.Jemand@web.de bist, dann könntest Du de.web.irgendjemand.* als Prefix für Deine Namespaces nehmen.
Das sind ein paar Anmerkungen von meiner Seite. Gibt bestimmt noch mehr zu sagen, aber das ist, was mir jetzt noch so aufgefallen ist. Und an der Funktionalität habe ich nicht viel geändert.
Ok, hat sich jetzt etwas überschnitten - sorry dafür und danke für das Posten des Codes. Ich schaue da gleich auch noch mal drauf um weitere Veränderungen zu sehen.
Ich finde es gut, wenn Ihr als Gruppe versucht zusammen etwas zu entwickeln. So könnt Ihr euch hoffentlich gegenseitig auch beim Verständnis der einzelnen Themen helfen. Dabei wünsche ich euch viel Spass und viel Erfolg.
Bei Problemen helfen wir hier immer gerne und Ihr seid hier immer herzlich willkommen.
Bezüglich Kartenverwaltung sind wir jetzt im grünen Bereich oder sind da jetzt noch Probleme offen?
Todo für Dich wäre ggf. noch die Nutzung einer HashMap statt ArrayList und evtl. meine Frage bzgl. dem verwendeten Logging. Und generell eine Dokumentation wäre nicht schlecht.
Die Klasse Terminal habe ich noch nicht angepackt, da dort etwas mehr Abhängigkeiten mit rein kommen. Hier wäre es evtl. sinvoll, dass die anderen Klassen für Schränke und so erst angegangen werden.
Ein Punkt, den Ihr euch überlegen solltest, wäre die Nutzung von Unit-Tests. Das wäre sehr sinnvoll um dann so die Klassen, die man erstellt, gleich testen zu können. Bei so einer Lerngruppe denke ich, dass es Sinn machen könnte.
Jaein, also das Programm klappt nicht ganz. die for each schleife muss irgendwie im Terminal stehen, da ich ja im terminal auf die einzelnen daten zugreiffen möchte. die "logging-methode" wurde so vom dozenten vorgegeben, deswegen haben wir sie benutzt.
nach dem das programm vollständig läuft, müssen wir auch die Tests durchführen.
nochmals vielen dank für deine hilfe.