Mehrere Objekte anlegen

Kickfree

Mitglied
Hallo Leute,
im folgenden Code werden zwei Objekte erstellt und in der ArrayList gespeichert, jedoch werden die erst eingegeben Daten von den zweit eingegeben Daten (im Array) überschrieben... Wie muss ich meinen Code ändern um das zu verhindern? Eventuell noch eine Klasse anlegen mit Konstruktor?

Java:
import java.util.ArrayList;
import java.util.List;

public class Main {

   public static void main(String[] args) {
      
        List<String[]> arrList = new ArrayList<String[]>();
       String[] arr = new String[3];
      
       String automarke = null;
       String modell = null;
       String leistung = null;
      
       //erstes Objekt
        Objekt o = new Objekt();
        o.setEingabe(arrList, arr, automarke, modell, leistung);

       //zweites Objekt
        Objekt e = new Objekt();
        e.setEingabe(arrList, arr, automarke, modell, leistung);
        e.ausgabe(arrList, arr);
   }
}

Java:
import java.util.List;

public class Objekt {
  
   public void setEingabe(List<String[]> arrList, String[] arr, String automarke, String modell, String leistung) {
        arr[0] = automarke = StdInput.readString("Automarke: ");
        arr[1] = modell = StdInput.readString("Modell: ");
        arr[2] = leistung = StdInput.readString("Leistung: ");
        arrList.add(arr);
   }
  
   public void ausgabe(List<String[]> arrList, String[] arr){
       for(int i=0; i<arrList.size(); i++){
           System.out.println(i + ". Datensatz:");
           for(int x=0; x<arr.length; x++){
               System.out.println(arr[x]);
           }
       }
   }
}
 
Was möchtest du eigentlich tun ?? Was soll diese setEingabe denn machen ? Ob du da jetzt eine Instanz oder zehn von Object anlegst ist eigentlich völlig wurscht. Du übergibst ja alles was du so hast als Parameter an diese Methode ??!!
 
Es soll später gesagt werden können "neues Auto erstellen" und dann sollen über diese Methoden die jeweiligen Angaben in das Array gespeichert werden. Danach das Array in die ArrayList übergeben und diese, wenn es erwünscht ist, in eine .txt Datei speichern. (Das Speichern ist hier aber nicht relevant)
 
Hmm, solltest du dann nicht eine Klasse Auto erstellen die alle Attribute enthält die ein Auto so haben soll ? Und diese Autos kannst du ja in einne ArrayList aufnehmen. So wie du das angefangen hat wird das nichts.
 
Das dachte ich mir auch schon, die Attribute, die das Auto haben soll, sollen später in einem Array gespeichert werden und das Array dann in der ArrayList, so dass beliebig viele Arrays initialisiert werden können und nicht die Attribute direkt in die ArrayList.
 
Ja genau. Dann machst du dir eine Klasse "Auto" mit den Attributen "Marke", "Modell", "Leistung" und was immer du noch möchtest. Und in deiner main legst du die Auto-Objekte an, fragst evtl. vorher vom Benutzer die Daten dazu ab und machst einen passenden Konstruktor.
Dann kannst du die Autos in eine ArrayList einfügen und damit machen was immer du möchtest. So wäre wohl der richtige Weg.
 
Die Attribute sollen in einem Array gespeichert werden, das dann in die ArrayList. Muss ich dann das Array auch in die Auto-Klasse mit rein nehmen? Und die ArrayList leg ich als Instanzvariable in der Main an? Bin noch ziemlich neu in Java... Sorry für die dummen Fragen
 
Ich habe es jetzt so probiert:
Code:
public class Main {
    public static void main(String[] args) {
      
        String marke = null;
        String modell = null;
        String leistung = null;
    
        Auto a = new Auto();
        a.setMarke(marke);
        a.setModell(modell);
        a.setLeistung(leistung);
        a.uebergabe();
      
        Auto b = new Auto();
        b.setMarke(marke);
        b.setModell(modell);
        b.setLeistung(leistung);
        b.uebergabe();
      
      
        b.ausgabe();
    }
}

Code:
import java.util.ArrayList;
import java.util.List;

public class Auto {
    List<String[]> arrList = new ArrayList<String[]>();
    String[] arr = new String[3];
    String marke;
    String modell;
    String leistung;
  
    Auto(){
    }
  
    public String getMarke() {
        return marke;
    }

    public void setMarke(String marke) {
        this.marke = marke;
        marke = StdInput.readString("Automarke: ");
        arr[0] = marke;
    }

    public String getModell() {
        return modell;
    }

    public void setModell(String modell) {
        this.modell = modell;
        modell = StdInput.readString("Modell: ");
        arr[1] = modell;
    }

    public String getLeistung() {
        return leistung;
    }

    public void setLeistung(String leistung) {
        this.leistung = leistung;
        leistung = StdInput.readString("Leistung: ");
        arr[2] = leistung;
    }
  
    public void uebergabe(){
        arrList.add(arr);
    }
  
    public void ausgabe(){
        for(String[] arr : arrList){
            for(int x=0; x<arr.length; x++){
                System.out.println(arr[x]);
            }
        }
    }
}

Jedoch überschreibt es mir jetzt das erste Array in der ArrayList, anstatt ein neues Element der ArrayList hinzuzufügen. Was muss ich verändern?

PS: könnte ich nicht die ganzen Setter und Getter-Methoden in eine große zsmfassen?
 
Das ist noch ein bisschen verquert. So wie du es jetzt gemacht hast hat jedes Auto-Objekt eine ArrayList von String-Arrays. Diese ArrayList gehört in die "main"-Klasse bzw. in die wo du was mit diesen Autos anfangen willst. Die Getter/Setter sind prinzipiell ok. Aber irgendwie wieder falsch implementiert. Du hast doch pro Auto drei Attribute: modell, marke und leistung. Die reichen doch. Was machst du mit diesem arr und arrList ??? Und ich würde empfehlen nicht in der setter-Methode von der Konsole einzulesen sondern in der main, vor dem anlegen des Autos. Und die Attribute dann im Konstruktor übergeben. Die Setter-Methoden sag ich mal kannst du dir sparen. Aus einem Audi wird doch nie ein Porsche oder ein Opel, usw.

Ausserdem würde ich eine toString() Methode implementieren die dir ein einzelnes Auto so als String aufbereitet wie du gerne möchtest.
 
Was hast du eigentlich mal mit dem ganzen vor ? Ich hätte die Auto-Klasse zunächst mal so gemacht:

Code:
import java.util.ArrayList;
import java.util.List;

public class Auto {
    String marke;
    String modell;
    String leistung;

    Auto(String marke, String modell, String leistung){
      this.marke = marke;
      this.modell = modell;
      this.leistung = leistung;
    }

    public String getMarke() {
        return marke;
    }

    public String getModell() {
        return modell;
    }

    public String getLeistung() {
        return leistung;
    }

    public String toString() {
        return "Auto: "+modell+" "+marke+" "+leistung;  //oder irgendeine andere Form
    }
}
 
Und die main erstmal zum testen so:

Code:
public class Main {
    public static void main(String[] args) {
    List<Auto> autoListe = new ArrayList<Auto>;
        String marke = null;
        String modell = null;
        String leistung = null;
 
         // hier die Daten für Auto 1 einlesen .....
        Auto a = new Auto(marke, modell, leistung);

        // die Daten für das zweite Auto einlesen .....
        Auto b = new Auto(marke, modell, leistung);

        autoListe.add(a);
        autoListe.add(b);
   
        // die Autos ausgeben:
        for (Auto auto: autoListe) {
             System.out.println(auto);
        }
    }
}

Keine Garantie für Imports, Schreibfehler etc. 🙂🙂
 
Das Programm soll mehrere Objekte vom Typ Auto erzeugen. Die Variablen marke, modell, leistung sollen, nach der Benutzereingabe, in ein Array übergeben werden. Dieses Array wird danach in die ArrayList übergeben. Die ArrayList soll nur als dynamischer Speicher dienen, um mehrere Autos/Arrays zu speichern, je nachdem wie viele der Benutzer eingeben will.
Ich hoffe das ist verständlich geschrieben 🙂

Ich habe deine Klassen mal eingefügt, wo müsste ich hier meinen Scanner/StdInput implementieren, dass ich für jedes Objekt andere Daten eingeben kann. Und was macht die Methode toString? (Tut mir echt leid für die dummen Fragen...)
 
Da hatte wohl jemand ein sehr ähnliches Problem wie du: http://forum.byte-welt.net/java-forum/java-grundlagen/18069-mehrere-objekte-anlegen.html.

Jedoch überschreibt es mir jetzt das erste Array in der ArrayList, anstatt ein neues Element der ArrayList hinzuzufügen. Was muss ich verändern?
Da schätze ich, hast du noch defizite bzgl. OOP. Die arrayliste ist abhängig vom Objekt und wird mit jedem Objekt auch korrekt neu angelegt. Ich würde dir empfehlen einfach mal nachzulesen, wo die Unterschiede sind. Hier gibt es einen längeren Wiki-Eintrag zu diesem Thema: http://wiki.byte-welt.net/wiki/Static_/_non-static_(Java)
 
Die Variablen marke, modell, leistung sollen, nach der Benutzereingabe, in ein Array übergeben werden
Warum sollen sie das denn ? Ist das eine Aufgabenstellung oder was hast du vor ? So wie ich es dir hingeschrieben hatte hast du alle Autos in der ArrayList und kannst jederzeit auf alles zugreifen. Und toString() wird u.a. aufgerufen wenn du z.B. System.out.println(auto); schreibst. Es hat die Aufgabe einen ausdruckbaren String in dem Format zurückzuliefern wie du es gerne sehen würdest.
 
Könnte ich nicht eine Methode in der Auto-Klasse für die Eingabe anlegen?
Und das mit den Arrays habe ich mir selbst überlegt, rein interessehalber. Wäre cool, wenn das funktionieren würde.
 
Du solltest dir evtl. nochmal das Thema, welches, wie du sagst, nicht von dir stammt (???), im anderen Forum ansehen...
Bezogen auf die 46 Zeilen von Spacerat, die dein Problem schon fast lösen, könntest du dort in die Klasse Car (hmm, alles übersetzt... schrecklich das. 😀) noch eine Methode "toArray()" hinzufügen, aber welchen Zweck sollte das noch haben?
Code:
public static class Car {
...
  public String[] toArray() {
    return new String[] {type, model, power};
  }

Ach ja... und die "toString()"-Methode, von JStein52 würde dort auch noch gut rein passen.
 
Zuletzt bearbeitet:
Ich habs jetzt mal so probiert:

Java:
import java.util.ArrayList;
import java.util.List;

public class Auto {
  
     private static List<Car> CARS = new ArrayList<Car>();
   
     public static Car neuesAuto(String marke, String modell, String leistung){
         return new Car (marke, modell, leistung);
     }
   
     public static class Car {
       
                private String marke, modell, leistung;
       
                private Car(String type, String model, String power) {
                    this.marke = type;
                    this.modell = model;
                    this.leistung = power;
                }
       
                public String getMarke() {
                    return marke;
                }
       
                public String getModell() {
                    return modell;
                }
       
                public String getLeistung() {
                    return leistung;
                }

                public void setCars(List<Car> cars) {
                    CARS = cars;  
                }
              
                 public static List<Car> getCars() {
                     return CARS;
                 }
        }
}

Java:
import java.util.ArrayList;
import java.util.List;

public class Eingabe {

    public void eingabe(){
        List<Auto.Car> CARS = new ArrayList<Auto.Car>();
        String marke, modell, leistung;
        boolean eingabe=true;
      
           while(eingabe) {
               String datens;
            
               marke = StdInput.readString("Automarke: ");
               modell = StdInput.readString("Modell: ");
               leistung = StdInput.readString("Leistung: ");
               Auto.Car nAuto1 = Auto.neuesAuto(marke, modell, leistung);
               nAuto1.setCars(CARS);
               CARS.add(nAuto1);
             
               datens = StdInput.readString("Noch einen Datensatz? ja/nein");
               if(datens.equals("nein")) {
                   eingabe=false;
               }
           }
         
           //test zur Ausgabe (funktioniert nicht)
           for (Auto.Car auto: CARS) {
                System.out.println(auto);
           }
    }
}

Jedoch funktioniert die Ausgabe nicht 😡

Habe es auch so probiert:
Java:
for(int i=0; i<CARS.size(); i++){
               System.out.println(CARS.get(i));
            }

Es wird nur "Auto$Car@2a139a55" ausgegeben...​
 
Zuletzt bearbeitet:
Hallo,

dass die Ausgabe so eigenartig aussieht, liegt daran, dass du den Tip von JStein52 nicht beachtet hast, eine toString-Methode zu schreiben. Wenn du sie nicht überschreibst, wird nur der Klassenname und eine Speicheradresse ausgegeben.

Daneben ist der gesamte Code noch nicht wirklich hübsch. Weshalb ist Car eine innere Klasse von Auto. Und weshalb hat die Klasse Eingabe eine Liste von Autos? Und warum hat Car die Methode getCars(), die ein Member von Auto zurückgibt.
Ich würde stattdessen drei Klassen (ohne innere Klassen) schreiben:
- Auto (mit den Membern marke, modell und leistung, einem Construktor, der die Werte setzt, gettern und einer toString-Methode)
- AutoListe (mit einer ArrayList von Autos, einer addAuto-Methode und einer toString-Methode, die die toString-Methode aller Autos aus der Liste aufruft),
- Eingabe (hier wird einmal ein Objekt von AutoListe erstellt und beliebig viele Autos erzeugt und in der Liste gespeichert)
 
Hey,
vielen Dank für deine hilfreiche Antwort 🙂
Habe es jetzt so gelöst:

Java:
public class Auto {
    private String marke, modell, leistung;
  
    public Auto(){
    }
  
    public Auto(String type, String model, String power) {
        this.marke = type;
        this.modell = model;
        this.leistung = power;
    }
       
    public String getMarke() {
        return marke;
    }
       
    public String getModell() {
        return modell;
    }
       
    public String getLeistung() {
        return leistung;
    }
  
    public String toString(){
        return "Automarke: " + marke +
               "\n   Modell: " + modell +
               "\n Leistung: " + leistung;
    }  
}
Java:
import java.util.ArrayList;
import java.util.List;


public class AutoListe {
     private static List<Auto> CARS = new ArrayList<Auto>();
   
     public void addAuto(){
         String marke, modell, leistung;
         String datens;
         boolean eingabe=true;
       
         while(eingabe) {
               marke = StdInput.readString("Automarke: ");
               modell = StdInput.readString("Modell: ");
               leistung = StdInput.readString("Leistung: ");
               Auto nAuto = new Auto(marke, modell, leistung);
                 CARS.add(nAuto);
           
               datens = StdInput.readString("Noch einen Datensatz? ja/nein");
               if(datens.equals("nein")) {
                   eingabe=false;
               }
           }
    }
   
     public void ausgabe(){
         for (Auto auto: CARS) {
             System.out.println(auto);
        }
    }
}
Java:
public class Eingabe {

    public void eingabe(){
        AutoListe liste = new AutoListe();
        liste.addAuto();
        liste.ausgabe();
    }
}

und funktioniert! 🙂
 
Schön, dass es nun funktioniert.
Die Klasse Auto gefällt mir so. Aber die Aufgaben der Klassen AutoListe und Eingabe sind eigenartig verteilt. Die AutoListe sollte wirklich nur eine Liste von Autos verwalten mit der Methode "void addAuto(Auto auto)" und einer weiteren Methode "String toString()". Die Abfrage, was für ein Auto erstellt werden soll, und das Erstellen der Autos ist Aufgabe der Klasse Eingabe.
Sei bitte nicht böse, wenn ich etwas penibel bin. Ich finde es aber wichtig, dass du gleich zu Anfang lernst, die Aufgabenbereiche von Klassen klar zu definieren.
 

Zurück
Oben