Diskuze: Změna objektu bez příkazu, jakto?

Java Java Změna objektu bez příkazu, jakto?

Avatar
cizula12
Člen
Avatar
cizula12:

Dobrý den, mám problém s tímto programem :/ Je to předepsaný program, který správně funguje, ale nevím si rady s významem s metodou vloz(), proč tento řádek "posledni = posledni.dalsi = new Uzel(vkladany);" přepíše i objekt "prvni",přesto že se tam vůbec o "prvni" nejedná, a zrovna i tu správnou větev "dalsi" ? Prosím o vysvětlení...

Pro lepší pochopení programu je tady zadání:

"Vytvořte třídu SpojovySeznam, která umí uchovávat prvky typu Object. Připravte metody void vloz(Object obj), Object vyjmiPrvniho() a void vypisSeznam()."

// univerzalni spojovy seznam

class Uzel {
Object prvek;
Uzel dalsi;

Uzel(Object o) {
prvek = o;
dalsi = null;
}

Uzel(Object o, Uzel dalsiUzel) {
prvek = o;
dalsi = dalsiUzel;
}

Object getPrvek() {
return prvek;
}

Uzel getDalsi() {
return dalsi;
}
}

class SpojovySeznam {
private Uzel prvni, posledni;
int pocet;

SpojovySeznam() {
prvni = posledni = null;
pocet = 0;
}

public boolean jePrazdny() {
return (prvni == null) ? true : false;
}

// vklada na konec
public void vloz(Object vkladany) {
if (jePrazdny() == true)
prvni = posledni = new Uzel(vkladany);
else
posledni = posledni.dalsi = new Uzel(vkladany);
pocet++;
}

public void vypisSeznam() {
Uzel akt = prvni;
while (akt != null) {
System.out.prin­tln(akt.prvek­.toString());
akt = akt.dalsi;
}
System.out.prin­tln("Pocet prvku: " + pocet);
}

public Object vyjmiPrvniho() {
Object o;
if (jePrazdny() == true)
return null;

pocet--;
o = prvni.prvek;
if (prvni != posledni)
prvni = prvni.dalsi;
else
prvni = posledni = null;

return o;
}

public int getPocet() { return pocet; }
}

public class SpojovySeznamTest {
public static void main(String[] args) {
SpojovySeznam s = new SpojovySeznam();
Integer i = new Integer(1);
Double d = new Double(3.14);
String a = "ahoj";
s.vloz(i);
s.vloz(d);
s.vloz(a);
s.vypisSeznam();
s.vyjmiPrvniho();
s.vypisSeznam();
}
}

 
Odpovědět 19.8.2014 1:36
Avatar
tomisoka
Redaktor
Avatar
tomisoka:

Nějak nechápu s čím máš problém, všechno funguje dobře a to co říkáš se tam neděje...

Jinak stačí psát :

if (jePrazdny())
System.out.println(akt.prvek);

A pro přehlednost používej vložit kód (viz obrázek)

 
Nahoru Odpovědět 19.8.2014 6:53
Avatar
cizula12
Člen
Avatar
cizula12:

Ten program je předloha, ten jsem nevytvořil... V popisovaném řádku "posledni = posledni.dalsi = new Uzel(vkladany);" mám nejasnosti... Když seznam vypisuji tak ho přeci vypisuji podle objektu "prvni", ale v té metodě(pokud není splněna podmínka) se podle příkazu přepisuje objekt poslední, ale když jsem jel postupně debug tak se tam i zároveň přepsal objekt "první", jakto? Je to správně, ale nevím proč to tam proběhlo... Zkuste si sám spustit program a pak postupně debug :-)

 
Nahoru Odpovědět 19.8.2014 10:19
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na cizula12
tomisoka:

Já si ho spustil už předtím a asi už vím co nechápeš.

prvni = posledni = new Uzel(vkladany);

ti vytvoří nový uzel na který ukazují "prvni" a "posledni"

posledni.dalsi = new Uzel(vkladany);

to ti vytvoří nový uzel, na který ukazuje "posledni.dalsi" a protože "posledni" ukazuje na stejný objekt jako "prvni" tak na tento nový uzel ukazuje i "prvni.dalsi"

posledni = posledni.dalsi;

"posledni" ukazuje na dalsi objekt

a toto se opakuje dál jen teď na "posledni" ukazuje zároveň "prvni.dalsi" pak na něj bude ukazovat "prvni.dalsi.dalsi" atd.
Ale tímto způsobem nepřepíšeš "prvni" protože ten ukazuje pořád na stejný objekt jen měníš co obsahuje tento objekt.

 
Nahoru Odpovědět 19.8.2014 11:25
Avatar
cizula12
Člen
Avatar
cizula12:

Ano, to je přesně to, co nechápu. Už se do toho pomalu dostavam, ale nechápu toto "protože "posledni" ukazuje na stejný objekt jako "prvni" tak na tento nový uzel ukazuje i "prvni.dalsi"", kde je to definované,že ukazují na stejný objekt a jak si to lze představit? Omlouvám se jsem začátečník, tak děkuji za trpělivost.

 
Nahoru Odpovědět 19.8.2014 13:07
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na cizula12
tomisoka:

No v paměti jsou objekty na nějaké adrese, protože je Java dynamický jazyk tak když zavoláš

new Uzel(vkladany);

tak ti vrátí adresu tohoto nového objektu

prvni + posledni = new Uzel(vkladany);

tady tu adresu dostanou "prvni" a "posledni", teď ukazují na stejnou adresu - tedy na stejný objekt - nově vytvořený uzel

můžeš si to ozkoušet třeba tímto :

System.out.println(prvni + " " + posledni);

pokud nemá třída metodu toString() tak vypisuje co je za třídu a pak adresu

A prosím používej "Odpovědět".

 
Nahoru Odpovědět 19.8.2014 14:06
Avatar
coells
Redaktor
Avatar
Odpovídá na tomisoka
coells:

Java je:

  1. staticky typovaný jazyk, nikoliv dynamicky
  2. nepodporuje adresy, ale reference
  3. to, zda je jazyk staticky nebo dynamicky typovaný, nemá nic společného ani s adresami, ani s referencemi
 
Nahoru Odpovědět 19.8.2014 14:22
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na coells
tomisoka:
  1. dobře to jsem měl vypustit
  2. ale chová se to více či méně stejně ne?
 
Nahoru Odpovědět 19.8.2014 14:29
Avatar
coells
Redaktor
Avatar
Odpovídá na tomisoka
coells:

Ne, adresa je ukazatel do paměti, reference je sémantický odkaz.

 
Nahoru Odpovědět 19.8.2014 14:38
Avatar
cizula12
Člen
Avatar
Odpovídá na tomisoka
cizula12:

Jo, už to chápu, díky :)

 
Nahoru Odpovědět 19.8.2014 19:00
Avatar
mkub
Redaktor
Avatar
mkub:

ludia, kedy sa naucite vkladat kod pomocou tlacitka na to urceneho?

 
Nahoru Odpovědět  +1 23.8.2014 18:10
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.