Referenzproblem

Vulymuz

Aktives Mitglied
Java:
class HeapQuiz {
  int id = 0;
  public static void main (String[] args) {
    int x = 0;
    HeapQuiz [] hq = new HeapQuiz[5];
    while (x < 3) {
      hq[x] = new HeapQuiz();
      hq[x].id = x; // Diesen Abschnitt verstehe ich nicht. Kann man mir bitte diese Zeile erklären?
      x = x + 1;
    }
   hq[3] = hq[1];
   hq[4] = hq[1];
   hq[3] = null;
   hq[4] = hq[0];
   hq[0] = hq[3];
   hq[3] = hq[2];
   hq[2] = hq[0];
   
   }
}

Ich finde bei dieser Aufgabe nicht heraus, welche der Referenzvariablen welches HeapQuiz-Objekt referenziert.

Lösung:
hq[0] referenziert nichts
hq[1] referenziert id = 1
hq[2] referenziert nichts
hq[3] referenziert id = 2
hq[4] referenziert id = 0

Wie gesagt, ich komme nicht auf die Lösung ... Wie kann es sein, dass hq[4] id = 0 referenziert, hq[2] aber nicht, obwohl auch hq[2] = hq[0]; ist (genau wie hq[4] = hq[0];)

Vielleicht liegt es auch daran, dass ich diesen Abschnitt einfach nicht verstehe:

Java:
hq[x].id = x;

Gruß!
 
Zuletzt bearbeitet:
S

SlaterB

Gast
> Wie kann es sein, dass hq[4] id = 0 referenziert, hq[2] aber nicht, obwohl auch hq[2] = hq[0]; ist (genau wie hq[4] = hq[0];)

weil zwischendurch hq[0] geändert wurde?
du kannst doch notfalls zwischen jedem einzelnen Code-Schritt alles ausgeben, wenn du schon an das Endergebnis glaubst
(ich habs nicht geprüft)

> dass ich diesen Abschnitt einfach nicht verstehe:

na id wird auf einen Wert gesetzt, 0, 1 oder 2
 

Kiri

Bekanntes Mitglied
Java:
   hq[3] = hq[1]; //hq[3] = id 1
   hq[4] = hq[1]; //hq[4] = id 1
   hq[3] = null;    //hq[3] = null
   hq[4] = hq[0]; //hq[4] = id 0
   hq[0] = hq[3]; //hq[0] = null
   hq[3] = hq[2]; //hq[3] = id 2
   hq[2] = hq[0]; //hq[2] = null

hq[1] wird nie geändert.
 

Vulymuz

Aktives Mitglied
Dachte ich mir ehrlich gesagt auch, aber in den Lösungen steht nur dass

hq[1] referenziert id = 1
hq[3] referenziert id = 2
hq[4] referenziert id = 0

Das heißt also, dass die Lösung in dem Falle falsch ist, weil hq[3] z. B. auch id = 1 referenziert ..., stimmts?
 

faetzminator

Gesperrter Benutzer
Natürlich stimmt die Lösung. Warum sollte sie nicht?
Wenn [c]hq[1][/c] nie geändert wurde, dann hat es logischerweise den Wert... 1 ;) Aber du denkst dir nur, dass [c]hq[1][/c] nie geändert wird? Du weisst aber schon, was diese Zuweisungen machen?
 
S

SlaterB

Gast
in beiden ungeklärten Auflistungen, die vielleicht Lösungen oder sonst was sind, vielleicht die gleichen oder unterschiedliche, steht
> hq[3] referenziert id = 2
dies ist auch korrekt,

wie kommst du zur Annahme, dass das falsch ist und völlig aus den Wolken erzählst du
> weil hq[3] z. B. auch id = 1 referenziert ..., stimmts?
?
dazu kann man nur sagen: nein, du liegst unbegründet falsch, das Programm und die Lösung(en?) passen zusammen,

sofern du noch Argumente/ Erläuterungen anbringen möchtest, kann man diese widerlegen,
ansonsten ist
> weil hq[3] z. B. auch id = 1 referenziert ..., stimmts?
etwa so wahrscheinlich wie eine grüne Sonne ;)
 

Crian

Top Contributor
Vielleicht wird es so klarer:

Java:
package forumProblems;

public class HeapQuiz {

    int id = 0;

    public static void main(String[] args) {
        int x = 0;
        HeapQuiz[] hq = new HeapQuiz[5];
        while (x < 3) {
            hq[x] = new HeapQuiz();
            hq[x].id = x;
            x = x + 1;
        }
        show(hq);
        hq[3] = hq[1];
        show(hq);
        hq[4] = hq[1];
        show(hq);
        hq[3] = null;
        show(hq);
        hq[4] = hq[0];
        show(hq);
        hq[0] = hq[3];
        show(hq);
        hq[3] = hq[2];
        show(hq);
        hq[2] = hq[0];
        show(hq);
    }

    private static void show(HeapQuiz[] hq) {
        for (int i=0; i<hq.length; ++i) {
            HeapQuiz q = hq[i];
            System.out.print(i + ":");
            if (null == q) {
                System.out.print("null");
            }
            else {
                System.out.print(q.id);
            }
            System.out.print(" ");
        }
        System.out.println();
    }

}

Ausgabe:

Code:
0:0 1:1 2:2 3:null 4:null 
0:0 1:1 2:2 3:1 4:null 
0:0 1:1 2:2 3:1 4:1 
0:0 1:1 2:2 3:null 4:1 
0:0 1:1 2:2 3:null 4:0 
0:null 1:1 2:2 3:null 4:0 
0:null 1:1 2:2 3:2 4:0 
0:null 1:1 2:null 3:2 4:0
 

Kiri

Bekanntes Mitglied
Das heißt also, dass die Lösung in dem Falle falsch ist, weil hq[3] z. B. auch id = 1 referenziert ..., stimmts?

Nein, es zählt nur die LETZTE Referenz, die vorherigen gehen verloren. Die letzte Referenz bei hq[3] ist
Java:
hq[3] = hq[2]; //hq[3] = id 2

damit verweist hq[3] auf id 2 und auf nichts anderes!
 

HimBromBeere

Top Contributor
Ich weiß gar nicht, wie du auf die Idee kommst, hq[3] könnte sowohl id2 als auch id1 referenzieren. Der Name einer Variablen kann immer nur genau ein Objekt referenzieren, in deinem Fall einen Integer. Wenn du der Variablen was neues zuweist, geht das, was bisher da drin stand, zwangsläufig verloren.
 

Vulymuz

Aktives Mitglied
Nein, es zählt nur die LETZTE Referenz, die vorherigen gehen verloren. Die letzte Referenz bei hq[3] ist
Java:
hq[3] = hq[2]; //hq[3] = id 2

damit verweist hq[3] auf id 2 und auf nichts anderes!

Danke, ich glaube, ich verstehe es langsam.

Weil hq[0] z. B. hq[3] referenziert, hq[3] bis zu dieser Stelle jedoch null (also nichts) referenziert, referenziert auch hq[0] nichts, hm? Gilt für hq[2] genau so.
 
S

SlaterB

Gast
hmm, ja,
eine Arrayzuweisung sollte man natürlich verstehen wenn man das macht,

aber das versuchst du vielleicht gerade zu lernen, bisschen tricky Programm dafür ausgesucht, aber letzlich durchaus genau dieses Thema,
also gut, dann lernst du es eben hierbei
 

Vulymuz

Aktives Mitglied
Ja, ich lese mir zurzeit das Buch "Java von Kopf bis Fuß" durch. Dort steht von den Autoren, dass die Übungen extra ein wenig schwieriger gestaltet sind, da man so besser lernen kann.

Danke euch jedenfalls, wie immer eine große Hilfe (btw wurde genau das auf der nächsten Seite erläutert - aber ich wollte das Programm unbedingt selber lösen und selber drauf kommen bzw. es selber verstehen, ehe ich weiterlese ... ^^)
 

faetzminator

Gesperrter Benutzer
Nein, das ist inkorrekt. Darum kommst du auch auf die falsche Lösung. Merk dir, sobald ein [c]=[/c] verwendet wird, hat das keine äusseren Auswirkungen. Als Beispiel mit einem [c]int[/c]-Array:
Java:
public void foo(int[] array) {
    array[0] = 0;
}
Hier kriegt der Aufrufer den Wert mit, da in dem übergebenen Array ein Wert geändert wird.
Java:
public void foo(int[] array) {
    int[] secondArray = new int[] {0};
    array = secondArray;
}
Hier wird die Referenz der Variable [c]array[/c] geändert. Der Aufrufer kriegt aber vom "neuen" Array nichts mit, denn seine Variable zeigt immer noch auf das originale Array.
 

Vulymuz

Aktives Mitglied
Nein, das ist inkorrekt. Darum kommst du auch auf die falsche Lösung. Merk dir, sobald ein [c]=[/c] verwendet wird, hat das keine äusseren Auswirkungen. Als Beispiel mit einem [c]int[/c]-Array:
Java:
public void foo(int[] array) {
    array[0] = 0;
}
Hier kriegt der Aufrufer den Wert mit, da in dem übergebenen Array ein Wert geändert wird.
Java:
public void foo(int[] array) {
    int[] secondArray = new int[] {0};
    array = secondArray;
}
Hier wird die Referenz der Variable [c]array[/c] geändert. Der Aufrufer kriegt aber vom "neuen" Array nichts mit, denn seine Variable zeigt immer noch auf das originale Array.

Auf welchen Beitrag bezog sich das jetzt. Ich denke, das Problem ist schon gelöst?!
 

faetzminator

Gesperrter Benutzer
Ganz allgemein ;) Wurde während dem schreiben unterbrochen, darum kam der Beitrag erst so spät... Aber wenn du den Unterschied zwischen den beiden Methoden verstehst, dann verstehst du, wie Java mit Referenzen arbeitet.
 

Vulymuz

Aktives Mitglied
Danke, verstanden. Ein paar formale Fragen noch:

Java:
public void foo(int[] array) // Warum steht das "int[] array" in den runden Klammern und nicht erst nach den geschweiften Klammern? Geht das auch? Unterschied?{
    array[0] = 0;
}

Java:
public void foo(int[] array) {
    int[] secondArray = new int[] {0}; // Was bedeutet das {0}? Dass secondArray den Wert 0 hat?
    array = secondArray;
}
 

Ebenius

Top Contributor
Java:
public void foo(int[] array) // Warum steht das "int[] array" in den runden Klammern und nicht erst nach den geschweiften Klammern? Geht das auch? Unterschied?{
    array[0] = 0;
}
[c]foo[/c] ist eine Methode, [c]array[/c] ist ein Argument der Methode. Wenn man die Methode aufruft, muss man das Argument mit angeben. Das Array wird also außerhalb der Methode (vom Aufrufer) initialisiert. Wenn [c]int[] array[/c] in den geschweiften Klammern stünde, wäre [c]array[/c] kein Argument sondern eine lokale Variable. Die müsste dann auch innerhalb des Methodenrumpfes initialisiert werden.

Java:
public void foo(int[] array) {
    int[] secondArray = new int[] {0}; // Was bedeutet das {0}? Dass secondArray den Wert 0 hat?
    array = secondArray;
}
[c]new int[] { 0 }[/c] legt ein neues [c]int[/c] array an, das die Länge 1 hat und als nulltes Element den Wert [c]null[/c] hat.

Das hätte den gleichen Effekt:
Java:
int[] secondArray = {0};
… und das auch:
Java:
int[] secondArray;
secondArray = new int[] {0};
… und das auch:
Java:
int[] secondArray = new int[1];
secondArray[0] = 0;
… und das auch:
Java:
int[] secondArray;
int[] secondArray = new int[1];
secondArray[0] = 0;

[EDIT]Bei meinen letzten beiden Beispielen könnte man sogar die Zeile [c]secondArray[0] = 0;[/c] weglassen weil das Array in der Zeile davor ohnehin mit Nullen gefüllt wird.[/EDIT]

Ebenius
 
Zuletzt bearbeitet:

faetzminator

Gesperrter Benutzer
In meinem Beispiel gehts kurz gesagt darum, dass in irgendeinem Array in Index 0 der Wert 0 gesetzt wird. Ein Mal im Array, welches per Parameter übergeben wird, und ein Mal erzeug ich es selbst und weise es dem Parameter zu. Führ den Code einfach aus und schau dir in den aufrufenden Methode den Wert von [c]array[0][/c] an - welcher vorteilhafterweise natürlich vorher nicht mit 0 gefüllt wird.
 

Neue Themen


Oben