# magisches Quadrat



## obelixpp (15. Dez 2011)

Guten Tag zusammen,
nachdem ich so langsam verzweifel hoffe ich das mir hier geholfen werden kann.
Ich habe folgende Aufgabenstellung (unten nachzulesen) und komme nicht weiter, weil ich leider keinen
Plan habe was genau toString sein soll. Ich habe schon alle Unterlagen von den Vorlesungen durchgesucht aber nichts dazu gefunden.




> Aufgabenstellung Teil II
> Schreiben Sie ein Programm, welches ein Feld mit drei Zeilen und drei Spalten erzeugt und ausgibt;
> jede Zelle enthält eine Ziffer zwischen 1 und 9, wobei jede Ziffer nur genau einmal vorkommt.
> Ein Beispiel für ein gültiges Feld wäre:
> ...



Für die Klasse RandomCell habe ich bis jetzt folgendes geschrieben:


```
package Aufgabe2;

public class RandomCell 
{
	int value =(int) (Math.random()*10);
		
	public int getValue()
	{
		return value;
	}
	
	void setValue(int value)
	{
		this.value = value;
	}
}
```

getter und setter Methoden sind ja forhanden und auch die zahl zu berechnen war jetzt nicht wirklich die schwierigkeit nur wie gesagt habe ich keine Ahnung wie ich weitermachen soll.

EDIT:// Da ich gerade gesehen habe das das Thema verschoben worden ist, wollte ich nur noch kurz sagen das ich hier natürlich keine fertige Lösung erwarte, sondern Hilfe dabei dieses Problem mit dem toString zu verstehen wäre sehr nett.


----------



## Gast2 (15. Dez 2011)

Die Hilfe: 

Java API 
Class Object 

toString

public String toString()

    Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

    The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

         getClass().getName() + '@' + Integer.toHexString(hashCode())


    Returns:
        a string representation of the object.


----------



## obelixpp (15. Dez 2011)

kappesf hat gesagt.:


> Die Hilfe:
> 
> Java API
> Class Object
> ...



Kann ich das so verstehen das ich mit dieser Methode "toString" einfach alles mögliche "anschaulich" darstellen lassen kann?
Aber wo wäre dann der Sinn darin?
Ich könnte doch auch einfach "System.out.println" nutzen für etwas auszugeben?
Bzw. wie könnte ich mit dem toString etwas "formatiert" abspeichern?


----------



## SlaterB (15. Dez 2011)

noch ein Hinweis:
du könntest hier sogar 'java was ist tostring' in eine Suchmaschine eintippen und bekommst allerlei Hinweise,
etwa
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 10.2 Object ist die Mutter aller Klassen
10.2.2 Objektidentifikation mit toString()


----------



## obelixpp (15. Dez 2011)

SlaterB hat gesagt.:


> noch ein Hinweis:
> du könntest hier sogar 'java was ist tostring' in eine Suchmaschine eintippen und bekommst allerlei Hinweise,
> etwa
> Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 10.2 Object ist die Mutter aller Klassen
> 10.2.2 Objektidentifikation mit toString()



Ich habe mir auch schon bei oracle die docs angeschaut, ich glaube mein problem ist eher das ich noch nicht wirklich weiß was ich mit dieser methode tostring anfangen kann.
jemand vllt ein konkretes beispiel?


----------



## SlaterB (15. Dez 2011)

genau meinen Link lesen?
dort steht für was toString() verwendet wird, es gibt Beispiele (Player) usw...


----------



## Marco13 (15. Dez 2011)

> Jedes Objekt sollte sich durch die Methode toString() mit einer Zeichenkette identifizieren und den Inhalt der interessanten Attribute als Zeichenkette liefern. ...
> Das Angenehme ist, dass toString() automatisch aufgerufen wird, wenn die Methoden print() oder println() mit einer Objektreferenz als Argument aufgerufen werden. Ähnliches gilt für den Zeichenkettenoperator + mit einer Objektreferenz als Operand.



Zugegeben: Das könnte man ... "zugänglicher" formulieren....



> ann ich das so verstehen das ich mit dieser Methode "toString" einfach alles mögliche "anschaulich" darstellen lassen kann?



Es geht nicht nur um "anschaulich", sondern darum, schnell und einfach Informationen über ein Objekt ausgeben zu können. Eine Klasse "Person" könnte z.B. eigenschaften haben wie Vorname, Nachname, Alter... Und es ist eben praktisch, wenn bei 
System.out.println(einePerson);
genau diese Informationen direkt ausgegeben werden, und man nicht
System.out.println("Vorname: "+einePerson.getVorname());
System.out.println("Nachname: "+einePerson.getNachname());
System.out.println("Alter: "+einePerson.getAlter());
hinschreiben muss. Und das erreicht man, indem man toString passend überschreibt. In deinem Fall geht es nur um diese Gitterzellen - man könnte da auch eine andere Methode überschreiben und explizit aufrufen, aber toString bietet sich eben an...


----------



## obelixpp (16. Dez 2011)

Marco13 hat gesagt.:


> Zugegeben: Das könnte man ... "zugänglicher" formulieren....
> 
> 
> 
> ...



Vielen vielen Dank für diese Beschreibung ich glaub ich habe es jetzt verstanden.
Also könnte das hier schon die Lösung für mein Problem sein?


```
public String toString() 
	  { 
	    return "[" + value + "]"; 
	  }
```

und wenn ich diesen Wert nachher aufrufen möchte für meinen würfel zu füllen nutze ich quasi einfach


```
RandomCell array = new RandomCell();
array.toString();
```

oder habe ich da noch etwas übersehen?


----------



## timbeau (16. Dez 2011)

```
RandomCell array = new RandomCell();
System.out.println(array.toString());
```


----------



## SlaterB (16. Dez 2011)

das sieht schon brauchbar aus, wobei der toString() Aufruf für sich keinen Sinn macht, der Rückgabewert, der erzeugte String wird nicht genutzt,
für eine einzelne Zelle ist 'array' auch ein grausiger Variablenname


----------



## obelixpp (16. Dez 2011)

Also ich habe es jetzt mal so umgeschrieben:


```
public class RandomGrid 
{
	RandomCell array[][] = new RandomCell[3][3];
	
	public static void main(String[] args)
	{
		
	}
	
	void init()
	{
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk] = value;	// Wert einsetzen mit dem das array an dieser Stelle gefüllt werden soll.
				System.out.print(array[waag][senk]+"\t");
			}
			System.out.println();
		}
	}
}
```

Momentan hänge ich an diesem Aufgabenteil,



> Diese Klasse stellt ein Feld dar. Das Feld ist ein zwei-dimensionales Array mit 3 Zeilen und 3 Spalten
> vom Typ RandomCell (Bezeichner = array).



zu allererst verstehe ich nicht wirklich wie ein Array vom Typ RandomCell sein kann, also kann ich quasi diesen Typ RandomCell den ich ja selbst quasi erstellt habe gleichsetzen mit anderen Datentypen wie int,String etc.?

und jetzt wollte ich das Array mit den Werten aus der anderen Klasse RandomCell füllen, die Variable dafür hatte ich value genannt allerdings weiß ich nicht wie ich jetzt aus der Klasse RandomGrid auf diesen Wert in der Klasse RandomCell zugreifen kann.


----------



## SlaterB (16. Dez 2011)

> also kann ich quasi diesen Typ RandomCell den ich ja selbst quasi erstellt habe gleichsetzen mit anderen Datentypen wie int,String etc.?
ja

> das Array mit den Werten aus der anderen Klasse RandomCell füllen
+
> wie ich jetzt aus der Klasse RandomGrid auf diesen Wert in der Klasse RandomCell zugreifen kann

da hast du eine falsche Sichtweise, du würdest ein int-Array auch nicht mit 'Werten aus der anderen Klasse' int befüllen, 
mal abgesehen davon dass int keine richtige Klasse ist,

es gibt keine bestimmen Werte aus der anderen Klasse, schon gar nicht nur einen 'diesen Wert',
sondern es es gibt die Klasse RandomCell und jeder kann beliebig RandomCell-Objekt erstellen so wie ints und Strings,

in deiner Doppelschleife kannst du der aktuellen Array-Position ein neu erstelltest RandomCell-Objekt zuweisen,
schon hast du am Ende 9 Stück,
nicht 9 bestimmte, einfach nur 9 neue

wie man Objekte einer Klasse erzeugt ist ein Grundlagenthema


----------



## obelixpp (16. Dez 2011)

SlaterB hat gesagt.:


> > also kann ich quasi diesen Typ RandomCell den ich ja selbst quasi erstellt habe gleichsetzen mit anderen Datentypen wie int,String etc.?
> ja
> 
> > das Array mit den Werten aus der anderen Klasse RandomCell füllen
> ...



Achso, das mit der falschen Sichtweise habe ich glaube ich verstanden.
Ich darf die Klassen beispielsweise nicht so wie mehrere Excel Tabellenblätter sehen wo ich verschiedene Werte hin und her "verlinken" kann.
Sondern ich kann nur ein neues Objekt der Klasse RandomCell die ich ja erstellt habe, erstellen und dieses neue Objekt bekommt dann quasi den "Wert" den ich in der Klasse RandomCell definiert habe also in meinem Falle wird für dieses Objekt immer irgendeine Zahl zwischen 1-9 gewählt?

Ich habe es mal so umgeschrieben:


```
public class RandomGrid 
{
	RandomCell array[][] = new RandomCell[3][3];	
	RandomCell fill = new RandomCell();
	
	public static void main(String[] args)
	{
		init();
	}
	
	void init()
	{
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk] = fill;	// Wert einsetzen mit dem das array an dieser Stelle gefüllt werden soll.
				System.out.print(array[waag][senk]+"\t");
			}
			System.out.println();
		}
	}
}
```

Allerdings bekomme ich jetzt immer die Meldung: Cannot make a static reference to a non static method


----------



## SlaterB (16. Dez 2011)

von der statischen main aus kannst du eben keine nichtstatische Methode aufrufen, erstelle ein RandomGrid-Objekt
und rufe dort vom Konstruktor aus init() auf oder stecke den Code in den Konstruktor,

und im Moment hast du nur ein cell-Objekt, welches du an alle Array-Positionen schreibst,
dann würde sich eine Wertänderung überall auswirken, denn alles ist ja dieselbe Zelle,
erstelle lieber 9 unterschiedliche Zellen, eben genau in Schleife, keine Variablen zu RandomCell außerhalb (vorerst)

> das mit der falschen Sichtweise habe ich glaube ich verstanden.
klingt ansonsten ganz gut, ja


----------



## timbeau (16. Dez 2011)

static void ....

Jein, 

du hast deine Klasse RandomGrid, in dieser erstellst du EIN Objekt der Klasse RandomCells. Und dieses füllst du mit festen Werten in deiner init-Methode. 

Du könntest diese init-Methode auch in die RandomCells-Klasse auslagern. Grundsätzlich ist jedes Zelle per Definition von int immer 0.


----------



## obelixpp (16. Dez 2011)

timbeau hat gesagt.:


> static void ....
> 
> Jein,
> 
> ...



Leider ist mir per Aufgabenstellung vorgegeben wo ich welche Methoden habe, ich werde mich heute Abend wohl nochmal intensiv damit auseinandersetzen müssen.

Zu dem erstellen eines Objektes der Klasse RandomGrid, kann ich in der Klasse RandomGrid ein Objekt dieser Klasse gleichzeitig aufrufen oder wie kann ich mir das vorstellen?
Dieses ganze mit den Objekten und Klassen fällt mir noch sehr schwer.


----------



## obelixpp (16. Dez 2011)

Vielleicht kann sich das mal jemand angucken, ich komm einfach nicht weiter er meckert immer er könne nicht von int to RandomCell konvertieren.
ich bin echt am verzweifeln.


```
package Aufgabe2;

public class RandomGrid 
{
	RandomCell array[][];
	RandomCell value;
		
	public static void main(String[] args)
	{
		
	}
	
	void init()
	{
		array = new RandomCell[3][3];
	}
	
	void refresh()
	{
		value = new RandomCell();
		
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk]=value.getValue();
			}
			System.out.println();
		}
	}
	
	
	void clear()
	{
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk]=0;
				System.out.println(array[1][1]);
			}
			System.out.println();
		}
	}
	
	void show()
	{
		for (int waag=0; waag < array.length; waag++)
		{
			for (int senk=0; senk < array[waag].length; senk++)
			{
				array[waag][senk] = 0;
				System.out.print(array[waag][senk]+"\t");
			}
			System.out.println();
		}
	}
}
```


----------



## SlaterB (16. Dez 2011)

was ist array? wenn es ein Array von RandomCell-Objekten ist, dann haben da doch int-Werte nichts zu suchen,
denn int ist ja kein RandomCell-Objekt?!

für diesen absoluten Grundsatz war nun externe Hilfe nötig?
dann noch ein Tipp: bevor du mit Arrays hantierst, übe an einfachen Variablen:

```
int k = 4;
int j = new RandomCell();
RandomCell x = 4;
RandomCell y = new RandomCell();
```
zwei dieser Zeilen sind richtig, zwei sind falsch,
tja, auch wenn es bisschen hämisch klingt, auf dem Niveau bist du jetzt angelangt mit der letzten Frage,

welche Variablen hast du im Programm, welche Werte, was macht jede Code-Zeile im einzelnen,
solche Grundfragen doch besser genauer überlegen bevor du aufgibst und deine Aufgaben an andere weiterreichst

> er könne nicht von int to RandomCell konvertieren
besonders wenn dich der Kompiler so direkt hinweist, das sagt der doch nicht zum Spaß, 
mal Nachdenken was das bedeuten könnte


----------



## obelixpp (16. Dez 2011)

int j = new RandomCell();
RandomCell x = 4;

Das Array "array" soll vom Typ RandomCell sein, und wird in der Methode "init()" erzeugt.
Und in "RandomCell" sollen Zufallszahlen zwischen 1-9 gespeichert werden wo jede nur einmal vorkommen darf, und diese Zahlen sollen in einer Variable "value" vom Typ int gespeichert werden.
Jetzt weiß ich allerdings nicht wie ich diese Werte die ja in einer int Variable gespeichert sind in ein Array vom Typ RandomCell bekommen soll.


----------



## SlaterB (16. Dez 2011)

hör komplett auf über Zahlen und Werte und Zufall nachzudenken, 
es ist vorerst vollkommen egal was RandomCell für eine Klasse ist, was darin passiert, die Klasse kann auch vereinfacht erstmal als

```
public class RandomCell {

}
```
definiert werden,

in eine RandomCell-Variable kann nur ein RandomCell-Objekt rein,
im Array ist es absolut dasselbe, es kommen RandomCell-Objekte hinein,
nichts weiter ist dazu zu sagen,
überlege und ziehe Schlüsse


----------



## Pommes9485 (18. Dez 2011)

Dir muss klar sein, das int(also Zahlen) nur nichts, also wirklich überhaupt nichts mit deiner eigenen Klasse zutun haben. Du kannst sie weder vergleichen noch einander zuweisen. Du kannst ja auch nicht ein Auto mit einem Baum vergleichen oder sogar das Auto den Wert des Baum zuweisen.

Eine Array ist nur eine Aneinanderreihung von Werten der jeweiligen Klasse. Das heißt du kannst der Array:
	
	
	
	





```
int[] u = new int[49]
```
kein Wort zuwesien und auch mit der eigenen Klasse ist es nicht möglich. Stell dir die Array vor, als Ketten die die Autos zusammenhalten. Trotzdem kannst du nicht die Autos mit dem Baum vergleichen.


----------



## obelixpp (20. Dez 2011)

SlaterB hat gesagt.:


> von der statischen main aus kannst du eben keine nichtstatische Methode aufrufen, erstelle ein RandomGrid-Objekt
> und rufe dort vom Konstruktor aus init() auf oder stecke den Code in den Konstruktor,
> 
> und im Moment hast du nur ein cell-Objekt, welches du an alle Array-Positionen schreibst,
> ...



Ich hab das Programm jetzt soweit fast fertig, nur steh ich im Moment total aufem Schlauch, und zwar bin ich zu blöd 9 verschiedene Cell Objekte in einer for Schleife erstellen zu lassen..


```
// schreibt neue Zufallszahlen in alle Zellen des Arrays
	void refresh()
	{
		value = new RandomCell(0);
		value.getValue();
		
		RandomCell wert[] = new RandomCell[9];
		
		for(int a=0; a < wert.length; a++)
		{
			wert[a] = value;
			//System.out.println("Wert: "+value);
		}

		for(int i=0; i < array.length; i++)
		{
			for(int j=0;j<array[i].length;j++)
			{
				array[i][j] = value;
			}
		}
		
	}
```


----------



## SlaterB (20. Dez 2011)

tja,
[c]= value;[/c]
ist in beiden Schleifen schlecht,
dir ist die Formulierung
[c]= neues Cell-Objekt[/c] wirklich nicht bekannt?

obwohl du an anderer Stelle, für die Variablen value, problemlos
[c]= neues Cell-Objekt[/c] 
stehen hast, in vorherigen geposteten Code schon gesehen (edit: in diesen aktuellen Code auch..)?

was macht für dich den Unterschied aus, einer Variablen ein neues Objekt zuzuweisen oder einer Array-Position?
da gibt es keinen Unterschied


----------



## obelixpp (20. Dez 2011)

SlaterB hat gesagt.:


> tja,
> [c]= value;[/c]
> ist in beiden Schleifen schlecht,
> dir ist die Formulierung
> ...



Danke, für diesen Hinweis :toll:

Ich glaube ich denk die meiste Zeit einfach zu kompliziert.


----------



## obelixpp (21. Dez 2011)

SlaterB hat gesagt.:


> dir ist die Formulierung
> [c]= neues Cell-Objekt[/c] wirklich nicht bekannt?



Ich denke doch mal das es einfach bedeutet das ich irgendeiner variable die beliebig sein kann ein neues Objekt vom Typ RandomCell zuweise.


----------



## SlaterB (21. Dez 2011)

denke ich doch auch und frage daher dich, was du da eigentlich fragst


----------



## obelixpp (21. Dez 2011)

SlaterB hat gesagt.:


> denke ich doch auch und frage daher dich, was du da eigentlich fragst



Alles klar, ich verraffe einfach oftmals die zusammenhänge noch
aber hier gilt wohl auch learning by doing :rtfm:


----------



## obelixpp (23. Dez 2011)

Ich wollte überprüfen ob in dem array zweimal dieselbe Zahl vorkommt aber irgendwie will es nicht so wie ich will,
jemand eine Idee wie ich daran gehen könnte?


----------



## obelixpp (23. Dez 2011)

Ich habe jetzt soweit meine Lösungsidee geschrieben aber es funktioniert nicht, hat vielleicht jemand eine Idee woran das liegt?


```
boolean wert = false;
		while(wert == false)
		{
		
			for(int i=0; i < array.length; i++)
			{
				for(int j=0;j<array[i].length;j++)
				{	
					array[i][j] = new RandomCell(0);
				}
			}
		
			for(int k=0; k < array.length; k++)
			{
				for(int l=0;l < array[k].length; l++)
				{
					if(array[k] == array[l])
					{
						wert = false;
					}
					else
						wert = true;
				}
			}
		}
```


----------



## Firephoenix (23. Dez 2011)

Du hast eine 2-Dimensionale Datenstruktur, auf der Willst du eine Operation für jedes Element durchführen.

In den Oberen Zeilen findest du dafür ein Beispiel, hier ist die Operation: neues Element erzeugen.

Jetzt ändert sich deine Operation.
Du prüfst für jedes Element ob es nochmal in der Datenstruktur vorkommt.

Wie prüfst du ob ein Element in der Datenstruktur doppelt vorkommt?
Du gehst einmal über die komplette Datenstruktur und prüfst alle Elemente außer dem aktuellem.

Die Operation oben ersetzt du also strikt mit der Methode der suche, überlegst dir wann beim suchen der Fall eintritt, dass du beim aktuellem Element bist und fertig 

Gruß


----------

