OOP Albumverwaltung

Alina_C

Mitglied
Benötige Hilfe :(
Ich will über die Klasse
Code:
AlbumAdministration
die Klasse
Code:
Album
steuern.
Man kann Alben hinzufügen, Alben und die Infos darüber über eine ID ausgeben, Alben suchen, und Alben mittels der ID löschen.
Nun will ich aber auch Alben mittels Angabe von Künstlern (
Code:
artist
) löschen können.
Ich habe die Methode removeAlbum in der Klasse AlbumAdministration mittels String Parameter überladen. In der AlbumTestDrive.java steckt die main-Methode, wo auch zwei Alben erstellt werden, das zweite Album soll dann mittels Angabe eines Künstlers gelöscht werden - geschieht aber nicht. Was läuft da falsch?


Java:
package alben_test;

import java.util.Vector;


public class Album {
	private long id;
	private String title;
	private Vector <String> artists;
	private String publisher;
	private Integer year;
	private String asin;
	private static int nextId = 1; //1)

	public Album(){
		this.id = nextId; //1)
		this.artists = new Vector <String> ();
		this.title = "";
		this.publisher = "";
		this.asin = "";
		this.year = null;
		nextId++; //1)
	}
	
	public static int getNextId(){ //2)
		return nextId;
	}
	
	public long getId(){
		return this.id;
	}
	
	public void setTitle(String title){
		this.title = title;
	}
	
	public String getTitle(){
		return this.title;
	}
	
	public void addArtist(String artist){
		this.artists.add(artist);
	}
	
	public Vector <String> getArtists(){
		return this.artists;
	}
	
	public void setPublisher(String publisher){
		this.publisher = publisher;
	}
	
	public String getPublisher(){
		return this.publisher;
	}
	
	public void setYear(int year){
		this.year = new Integer(year);
	}
	
	public int getYear(){
		return this.year;
	}
	
	public void setAsin(String asin){
		this.asin = asin;
	}
	
	public String getAsin(){
		return this.asin;
	}
	
}


Java:
package alben_test;

import java.util.Iterator;
import java.util.Vector;

public class AlbumAdministration {
	Vector<Album> albums;

	public AlbumAdministration() {
		this.albums = new Vector<Album>();
	}

	public boolean addAlbum(long id, String title, Vector<String> artists,String publisher, int year, String asin) {
		for (int i = 0; i < this.albums.size(); i++) {
			if (this.albums.get(i).getId() == id) {
				return false;
			}
		}

		Album album = new Album();
		album.setTitle(title);
		album.setPublisher(publisher);
		album.setYear(year);
		album.setAsin(asin);
		
		for (Iterator<String> artistIter = artists.iterator(); artistIter.hasNext();) {
			album.addArtist(artistIter.next());
		}

		this.albums.add(album); //2)
		System.out.println(Album.getNextId());
		return true;
	}

	public void removeAlbum(long id) {
		for (int i = 0; i < this.albums.size(); i++) {
			if (this.albums.get(i).getId() == id) {
				this.albums.remove(i);
				break;
			}
		}
	}
	
	public void removeAlbum(String artist){
		for (int i = 0; i < this.albums.size(); i++){
			if (this.albums.get(i).getArtists().contains(artist)){
				this.albums.remove(i);
				break;
			}
		}
	}

	public String getAlbumStr(long id) {
		Album currAlbum;
		String albumStr = "Album not found!";

		for (Iterator<Album> iter = this.albums.iterator(); iter.hasNext();) {
			currAlbum = iter.next();

			if (currAlbum.getId() == id) {
				albumStr = currAlbum.getId() + ";" + currAlbum.getTitle() + ";";

				for (Iterator<String> authorIter = currAlbum.getArtists()
						.iterator(); authorIter.hasNext();) {
					albumStr += authorIter.next();

					if (authorIter.hasNext()) {
						albumStr += ",";
					}
				}

				albumStr += ";"+currAlbum.getPublisher()+";"+currAlbum.getYear()+";"+currAlbum.getAsin();
			}
		}

		return albumStr;
	}

	public Vector<Long> search(String searchStr) {
		Vector<Long> artistHits = new Vector<Long>();
		Album currAlbum;

		for (Iterator<Album> iter = this.albums.iterator(); iter.hasNext();) {
			currAlbum = iter.next();
			for (Iterator<String> artistIter = currAlbum.getArtists().iterator(); artistIter.hasNext();) {
				if (artistIter.next().contains(searchStr)) {
					artistHits.add(new Long(currAlbum.getId()));
				}
			}
		}
		return artistHits;
	}
}

Java:
package alben_test;

import java.util.Arrays;
import java.util.Vector;

public class AlbumTestDrive {
	public static void main (String[] args){
		AlbumAdministration albumAdmin = new AlbumAdministration();
		System.out.println(albumAdmin.addAlbum(1, "Nevermind", new Vector<String> (Arrays.asList(new String[]{"Nirvana"})), "Geffen, Universal", 1991, "B000003TA4"));
		System.out.println(albumAdmin.addAlbum(2, "Crossing All Over Vol.14", new Vector<String> (Arrays.asList(new String[]{"Clawfinger Godsmack Muse Donots"})), "Polystar", 2001, "B00005QJPC"));
		System.out.println(albumAdmin.getAlbumStr(1));
		System.out.println(albumAdmin.getAlbumStr(2));
		albumAdmin.removeAlbum("Muse");
		System.out.println(albumAdmin.getAlbumStr(2));
	}
	 
}
 
Zuletzt bearbeitet von einem Moderator:

Marc T.

Bekanntes Mitglied
Sehr schwer für mich durch deinen Code durchzusteigen^^

Funktioniert denn das löschen mit der ID?
Wenn ja, kann es nur daran liegen

Java:
if (this.albums.get(i).getArtists().contains(artist)){
      this.albums.remove(i);
      break;
}

Oder hieran:

Java:
 System.out.println(albumAdmin.addAlbum(2, "Crossing All Over Vol.14", new Vector<String> (Arrays.asList(new String[]{"Clawfinger Godsmack Muse Donots"})), "Polystar", 2001, "B00005QJPC"));

Stimmt vielleicht was mit denen Vektoren nicht.

EDIT:

Ich glaube ich habe es:
""Clawfinger Godsmack Muse Donots""

.contains() prüft ob der String "Muse" im Vektor vorhanden ist. Du hast
aber nur den String "Clawfinger Godsmack Muse Donots" im Vector....

In diesem Fall müsstest du auf den String nocheinmal die String-Methode
.contains() auf "Clawfinger Godsmack Muse Donots" anwenden.....

Trenne den String doch mal so:
"Clawfinger", "Godsmack", "Muse", "Donots"
 
Zuletzt bearbeitet:

Alina_C

Mitglied
das Löschen über ID klappt.
Java:
System.out.println(albumAdmin.addAlbum(2, "Crossing All Over Vol.14", new Vector<String> (Arrays.asList(new String[]{"Clawfinger Godsmack Rammstein Donots"})), "Polystar", 2001, "B00005QJPC"));
System.out.println(albumAdmin.getAlbumStr(2));

albumAdmin.removeAlbum(2);
System.out.println(albumAdmin.getAlbumStr(2));

Console:
Code:
2;Crossing All Over Vol.14;Clawfinger Godsmack Muse Donots;Polystar;2001;B00005QJPC
Code:
Album not found!
 
Zuletzt bearbeitet:

Marc T.

Bekanntes Mitglied
EDIT:

Ich glaube ich habe es:
""Clawfinger Godsmack Muse Donots""

.contains() prüft ob der String "Muse" im Vektor vorhanden ist. Du hast
aber nur den String "Clawfinger Godsmack Muse Donots" im Vector....

In diesem Fall müsstest du auf den String nocheinmal die String-Methode
.contains() auf "Clawfinger Godsmack Muse Donots" anwenden.....

Trenne den String doch mal so:
"Clawfinger", "Godsmack", "Muse", "Donots"

Falls dus übersehen hast ;)
 

Marc T.

Bekanntes Mitglied
War bisl schwer diese Verschachtelungen zu durchblicken ;)
Vielleicht machst du in Zukunft hier und da eine neue Zeile
oder eine Einrückung, zumindest was den Teil betrifft:
Java:
public class AlbumTestDrive {
    public static void main (String[] args){
        AlbumAdministration albumAdmin = new AlbumAdministration();
        System.out.println(albumAdmin.addAlbum(1, "Nevermind", new Vector<String> (Arrays.asList(new String[]{"Nirvana"})), "Geffen, Universal", 1991, "B000003TA4"));
        System.out.println(albumAdmin.addAlbum(2, "Crossing All Over Vol.14", new Vector<String> (Arrays.asList(new String[]{"Clawfinger Godsmack Muse Donots"})), "Polystar", 2001, "B00005QJPC"));
        System.out.println(albumAdmin.getAlbumStr(1));
        System.out.println(albumAdmin.getAlbumStr(2));
        albumAdmin.removeAlbum("Muse");
        System.out.println(albumAdmin.getAlbumStr(2));
    }
     
}
Dann findest du bestimmt auch selbst
viel schneller wo etwas nicht stimmt :D
 

Alina_C

Mitglied
Angenommen ich will nun eine InnerClass Asin in Album erstellen.
Sie soll die Instanzvariable private String value,
einen Konstruktor, welcher privae String value mit value inititalisiert
und die Methode public String getValue(); die die Instanzvariable value zurückgibt.

Hier mein Versuch:
Java:
package alben_test;

import java.util.Vector;


public class Album {
	private long id;
	private String title;
	private Vector <String> artists;
	private String publisher;
	private Integer year;
	private String Asin;
	private static int nextId = 1; //1)

	public Album(){
		this.id = nextId; //1)
		this.artists = new Vector <String> ();
		this.title = "";
		this.publisher = "";
		this.Asin = new Asin();
		this.year = null;
		nextId++; //1)
	}
	
	public static int getNextId(){ //2)
		return nextId;
	}
	
	public long getId(){
		return this.id;
	}
	
	public void setTitle(String title){
		this.title = title;
	}
	
	public String getTitle(){
		return this.title;
	}
	
	public void addArtist(String artist){
		this.artists.add(artist);
	}
	
	public Vector <String> getArtists(){
		return this.artists;
	}
	
	public void setPublisher(String publisher){
		this.publisher = publisher;
	}
	
	public String getPublisher(){
		return this.publisher;
	}
	
	public void setYear(int year){
		this.year = new Integer(year);
	}
	
	public int getYear(){
		return this.year;
	}
	
	public void setAsin(String asin){
		this.Asin = new Asin(asin); 
	}
	
	public String getAsin(){
		return this.getAsin();
	}
	
	class Asin{
		private String value;
		
		public Asin(String value){
			this.value = value;
		}
		
		public String getAsin(){
			return value;
		}
	}
}

Dabei gibt es zwei Probleme :
in Zeile 20
Code:
this.Asin = new Asin();
was stimmt da nicht? Ich benötige doch ein neues Asin Objekt für jede Album-Instanz
in Zeile 66
Code:
this.Asin = new Asin(asin);
- cannot convert from Album.Asin to String :shock:
 
Zuletzt bearbeitet:
B

bygones

Gast
Soll nur eine Übung für innere Klassen sein.

mhm - zwar nicht das beste, aber ok ;-)

Java:
private String Asin;
du hast noch asin (variablen klein schreiben) als String definiert, muss aber ja ein Asin sein

Java:
this.Asin = new Asin(asin);
deine innere Klasse hat keinen Konstruktor, der ein String nimmt.
 

Alina_C

Mitglied
Sorry, in welcher Zeile meinst du ?

Und zum Konstruktor: ist nicht
Java:
		public Asin(String value){
			this.value = value;
		}
der Konstruktor mit String?


Edit: Achso , klar du meinst die Instanzvariablen ganz oben - mist, was fürn doofer Fehler.
 
Zuletzt bearbeitet:

Alina_C

Mitglied
also
Code:
private Asin asin;
Dann bekomme ich in Zeile 20
Code:
this.asin = new Asin();
den Fehler constructor is undefined - dabei übergebe ich doch garnichts?

Edit:
Code:
this.asin = new Asin("");
Führt das zu den gewünschten Effekt? Oder benötige ich eine neue String-Instanzvariable, die an den Konstruktor übergeben wird? Auf diese Art oben bekommen doch alle Asin nur einen leeren String?

Riesenproblem. Bei der Ausführung bekomme ich nun
Code:
Exception in thread "main" java.lang.StackOverflowError
at alben_test.Album.getAsin(Album.java:70)
(....)
Zeile zwei der Exception wiederholt sich gefühlte 100 mal
 
Zuletzt bearbeitet:

Paddelpirat

Bekanntes Mitglied
Mit this.getAsin() rufst du endlos lange die Methode getAsin() in der Klasse Album auf. Daher die Exception (gefühlte 100 - wahrscheinlich noch öfter - Mal ) ;-)

Wenn du schon eine eigene Klasse
Code:
Asin
hast, dann solltest du in der Klasse
Code:
Album
den
Code:
String Asin
in ein Object
Code:
Asin asin
umschreiben.

Anschließend könntest du in der Klasse
Code:
Album
die Methode
Code:
getAsin()
z.B. in eine Methode
Code:
getAsinValue
umschreiben. Etwa so (nicht explizit getestet):

Java:
package alben_test;
 
import java.util.Vector;
 
 
public class Album {
    private long id;
    private String title;
    private Vector <String> artists;
    private String publisher;
    private Integer year;
    private Asin asin;
    private static int nextId = 1; //1)
 
    public Album(){
        this.id = nextId; //1)
        this.artists = new Vector <String> ();
        this.title = "";
        this.publisher = "";
        this.asin = new Asin();
        this.year = null;
        nextId++; //1)
    }
    
    public static int getNextId(){ //2)
        return nextId;
    }
    
    public long getId(){
        return this.id;
    }
    
    public void setTitle(String title){
        this.title = title;
    }
    
    public String getTitle(){
        return this.title;
    }
    
    public void addArtist(String artist){
        this.artists.add(artist);
    }
    
    public Vector <String> getArtists(){
        return this.artists;
    }
    
    public void setPublisher(String publisher){
        this.publisher = publisher;
    }
    
    public String getPublisher(){
        return this.publisher;
    }
    
    public void setYear(int year){
        this.year = new Integer(year);
    }
    
    public int getYear(){
        return this.year;
    }
    
    public void setAsin(String value){
        this.asin = new Asin(value); 
    }
    
    public String getAsinValue(){
        return asin.getValue();
    }
    
    class Asin{
        private String value;
        
        public Asin(String value){
            this.value = value;
        }
        
        public String getValue(){
            return value;
        }
    }
}
 

Alina_C

Mitglied
Also könnte ich auch folgendes schreiben:
Java:
	public String getAsin(){
		return asin.getAsin();
	}

Scheint auch zu klappen.

Also return this.getAsin(); ruft die selbe Methode, in der das return Statement steht auf?
Dann kommt es zu einer Endlosschleife. Wenn ich jetzt drüber nachdenke, wohl ein ziemlicher Anfängerfehler :oops:

Jedenfalls vielen Dank :)
 

Paddelpirat

Bekanntes Mitglied
Code:
this.getAsin();
ruft die Methode
Code:
getAsin()
in der aufrufenden Klasse auf. :)

Das kann schon mal etwas verwirrend sein. Und ja

Java:
public String getAsin(){
        return asin.getAsin();
    }

kannst du so bei deinem Code aufrufen. Allerdings empfehle ich dir die Methoden und Variablen besser zu benennen, damit du den Überblick behältst, was du aufrufst und was du als Rückgabewert erwartest.
 

Paddelpirat

Bekanntes Mitglied
Naja das mit dem besser benennen war auf die Klasse
Code:
Asin
bezogen. Wenn du in dieser Klasse dann eine Methode
Code:
getAsin
definierst, die einen String zurückgibt, ist das irgendwie komisch. Deswegen hatte ich die Methode in meinem vorletzten Post
Code:
getValue
genannt.

Aber rein theoretisch bräuchtest du die Klasse Asin ja nicht mal. Eine Alternative wäre:

Java:
package alben_test;
 
import java.util.Vector;
 
 
public class Album {
    private long id;
    private String title;
    private Vector <String> artists;
    private String publisher;
    private Integer year;
    private String asin;
    private static int nextId = 1; //1)
 
    public Album(){
        this.id = nextId; //1)
        this.artists = new Vector <String> ();
        this.title = "";
        this.publisher = "";
        this.asin = "";
        this.year = null;
        nextId++; //1)
    }
    
    public static int getNextId(){ //2)
        return nextId;
    }
    
    public long getId(){
        return this.id;
    }
    
    public void setTitle(String title){
        this.title = title;
    }
    
    public String getTitle(){
        return this.title;
    }
    
    public void addArtist(String artist){
        this.artists.add(artist);
    }
    
    public Vector <String> getArtists(){
        return this.artists;
    }
    
    public void setPublisher(String publisher){
        this.publisher = publisher;
    }
    
    public String getPublisher(){
        return this.publisher;
    }
    
    public void setYear(int year){
        this.year = new Integer(year);
    }
    
    public int getYear(){
        return this.year;
    }
    
    public void setAsin(String value){
        asin = value; //hier muss kein this stehen, da es keine lokale Variable asin in dieser Methode gibt
    }

    //public void setAsin(String asin){
    //    this.asin = asin; //<---Hier muss this stehen, da du unterscheiden musst zwischen lokalem und globalem asin.
    //}
    
    public String getAsinValue(){
        this.asin; //das this könntest du hier auch weg lassen.
    }
}

Ich hab da auch mal eine zweite Variante der
Code:
setAsin
-Methode rein geschrieben. Ich hoffe das ist verständlich und erklärt auch, wann du
Code:
this
brauchst und wann nicht.
 

Neue Themen


Oben