
Java - seznam
Zdravím,
mořím už se s tím několik hodin, a nemohu se dobrat žádného řešení.
Tak bych prosil o pomoc, pro Vás to bude nejspíše prkotina.
Mám 2 třídy.
První je hotová: Vec - má metody: getNazev(), jeSebratelna(), equals(), hashCode().
A my máme naprogramovat další třídu: Mistnost a následující metody.
* 1) Vlož věc do místnosti(Vec vec)
* - pokud již je stejné jméno - nepřidávat, jinak ano
* 2) Odeber věc z místnosti(String nazevVeci)
* - vrať instanci, pokud věc není tak vrať null
* 3) public Collerction<Vec> sebratelneVeci ()
* - vrací seznam věcí, které lze v místnosti sebrat - ne všechny!
Vkládám kod s mými marnými pokusy:
import java.util.Collection;
import java.util.ArrayList;
public class Mistnost
{
//== Datové atributy (statické i instancí)======================================
public ArrayList<Vec> seznamVeci = new ArrayList<Vec>();
public String nazevMistnosti;
//== Konstruktory a tovární metody =============================================
public Mistnost(String nazevMistnosti) {
this.nazevMistnosti = nazevMistnosti;
}
//== Nesoukromé metody (instancí i třídy) ======================================
public boolean vlozVec(Vec vec) {
for (Vec cokoli: seznamVeci) { //projdi seznam
if(vec.getNazev().equals(cokoli.getNazev())) { //porovnej název s názvama v seznamu
return false; //pokud se rovnají, tak nepřijdávej
}
else { //jinak - přidej do seznamu
seznamVeci.add(vec);
return true;
}
}
return true; //k tomu kroku nikdy nedojde???K čemu je?
}
public Vec odeberVec(String vec) {
for (Vec cokoli2: seznamVeci) {
if (vec.getNazev().equals(vec)) { //nefunguje vec.getNazev, proč???(nepřeloží překladač)
seznamVeci.remove(vec);
return vec;
}
return null;
}
}
public Collection<Vec> sebratelneVeci() {
return seznamVeci; //vrací celý seznam, jak jen ty které lze sebrat???
}
//== Soukromé metody (instancí i třídy) ========================================
}
Předem díky, uvítám vysvětlení jako tupce, M.
3 poradím až uvidím, jak vypadá třída Vec...
1) Nádhera - my jsme to dělali v hodinách vždy procházením, jaktože zde ho netřeba procházet?
"if (!seznamVeci.contains(vec))" - Nebo ho toto prochází též? - "Pokud seznamVeci neobsahuje vec, tak přidej věc" - tak jsem seznam musel projít, ne?
- jenom, jak by to vypadalo přes to procházení seznamu?
2)
Ale já když prohlížím seznamVeci, tak tam vidím i instance, které jsem právě odebral.
3)
V konstruktoru "věc"i si volíme "boolean sebratelna" a "String nazevVeci". Pak je přidáváme do seznamu v "Mistnost"
Vec.java
Mistnost.java
Když použiješ contains, tak už procházet nemusíš protože ten průchod je už v metodě contains...
Pokud chceš používat tu verzi s tím contains, musíš mít ve třídě Vec překryté metody hashcode a equals.
Geniální ... snad i všemu rozumím, ale chci se ujistit.
Raději použiju opět procházení seznamu, hrabání se v HashCodu nebo Equals bych evidentně schopný nebyl.
Zadáno bylo takto(ve třídě "Vec"), ale tuto třídu nemáme měnit(naštěstí :) ):
Ale ještě mám otázečky:
K druhé metodě: Změnil jsem seznamVeci.remove(cokoli2); ... protože "String vec" remove nemaže instanci.
Ke třetí metodě: Jsem si raději okomentoval - chápu to správně, když je isSebratelna() false, tak jakoby není???
A poslední otázka: Jak bych udělal abych přes konstrukor určil maximum seznamu, například aby seznam mohl mít například nejvýše 5 věcí.
Snad už přestanu otravovat. Jinak velké díky, M.
Ano, tak je to správně. Máš kolekci instancí Vec a vlastně odebíráš instanci String. Ta tam samozřejmě není...
Ano. Nemusíš testovat isSberatelna() == true. V Javě se stačí zeptat if (isSberatelna), pokud bude false, tak to do toho ifu neskočí. Jinak je to ok.
To je trochu problém, ArrayList je v Javě dynamická datová struktura, takže nemá omezenou kapacitu. Musel bys při přidávání prvku kontrolovat jestli seznamVeci.size() == maximum, pokud ano, tak prvek nepřidat.
Nebo použij klasické pole a jeho velikost si naalokuj podle parametru maximum.
Zdravím,
nakonec jsme měli omezovat přesně přes zmínění .size().
Jediné co jsem v testu nevěděl, bylo testování výpisu seznamu. > ?
Ještě otázečka: jaký je rozdíl mezi length() a size()? Vím, že jsme někde používala length(snad u polí, teď nevím), také jsem to nejdřív zkoušel a nefungoval to zde u toho seznamu. Jediné, co mě napadá, je, že length je délka něčeho omezeného(polí (Nebo pole mohou být i neomezená?)), zatímco size(se nastavuje něčemu co nemá length(seznam) -> pak ale nevím jaké je rozdíl u polí mezi length a size ... jen moje úvaha.
Předem díky, M.
lenght - je typicky u polí, které mají danou délku, zadává se už při alokaci a vrací pořád stejnou hodnotu
size() - vrací počet prvku které jsou skutečně v dané kolekci (u polí není)
Ten unit test má testovat co? Metodu seznamZastavek(), která vrací celý seznam? Pokud ano, tak:
Tak by to snad mohlo stačit...
PS: Předpokládám, že seznamZastavek() vrací aspon Collection.
Díky.
Je to přesně, jak říkáš, Collection seznamuZastávek.
Ještě bych prosil pomoc k seznamu s jedním cyklem. On teda nakonec snad funguje ve všech případech, ale přijde mi to strašně kostrbatý, přímo hranatý :).
Tím bych snad už mohl Vám dát odpočinout a skončit otravovat se seznamy (možná za čas s něčím jiným :) vtip :) )
M
Snad... píšu z hlavy, bez kompilátoru...
Reakce 1:
No :), možná je něco blbě u mě, ale opět nic - "variable zastavky might not have been initialized"
I přes rýpání jsem to nějak nebyl schopen zprovoznit.
Ze třídy seznamZastavek: Datový atribut + metoda.
Reakce 2:
Ehmm, já dávám těch mých 15 řádků dohromady půl dne, a Vy máte román za 5 minut :) no.
Nicméně, pokud má být toto jednodušší :) ... ono to právě má být v jedné metodě, aby se kliklo na přidat hráče, a "všechno se to udělalo samo"
-> Ale klidně toto nechte být -> nesejde na tom, hlavně že to "nějak" funguje :)
-> Já jen jestli v tom mém není nějaká základní logická chyba
-->> re:3metody: Hlásilo to nějaké chyby, vůbec mi to něchtělo přidat(možná to chtělo datový atribut(nevím)), rozeberu si to zítra, pokud ten kod vůbec zcela pochopím.
Zatím dík, dneska + pár hodin už ty kody nech´t zmizí ze světa :)
M
1)
Stačí udělat Zastavka[] zastavky = null;
2)Tvoje metoda funguje jenom do 99, a navíc nevím jestli dobře...
Tady máš odzkoušený a okomentovaný kód, včera jsem tam měl chybu.
Hrac.java
SeznamHracu.java
Těch privátních metody se neboj, nebudou na venek vidět. Dělám je proto, aby byl kód přehlednější a implementace metod co nejkratší.
EDIT: No, teď vidím i v tom mém řešení potenciální problém:
1) přidám hráče s číslem 1, přidá se
2) přidám hráče s číslem 34, přidá se
3) přidám hráče s číslem 0, přidá se s číslem 35
4) přidám dalšího hráče s číslem 0, přidá se s číslem 36
chtělo by to vychytat, ale zadání to myslím splňuje...
SeznamHracu.java verze 1.1
Tady je vidět, jak celkem jednoduchý problém může být záludný...
1) Překladač OK. Ale test skončí nezdarem :).
Samotný první řádek testu projde, s jakýmkoliv dalším už ne.
2) Počítám jen do 99, protože na dresu bývají jen dvě čísla :). Taky mi to nejdřív počítalo jako ve vaší verzi 1.0.
Jinak to Vaše funguje krásně, radši jsem si na to udělal novou třídu, už se mi to tam motalo :).
Dokonce i System.out.println u Vás vypisuje krásně jedno číslo, ne jak u mě, proto jsem si právě nebyl jist, protože mně vypisuje i čísla, která prochází, ačkoliv v set()u se objeví správné .). (Vlastně ve Vaší metodě getFirstFreePlayerNumber() System.out.printl vypisuje též dvě čísla, to by nemělo, ne?, ale nevím)
Ale toto je pro mě zatím moc, některé konstrukce jsem zatím ani neviděl, natož abych je vytvořil.
Pokusím se zjistit řešení 2), tak uvidíme :).