Java týden Body zdarma
Využij podzimních slev a získej od nás až 40 % bodů zdarma! Více zde
Pouze tento týden sleva až 80 % na Java e-learning!

Lekce 11 - ArrayList v Javě

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Gettery a settery v Javě, jsme si řekli něco o datu a času. Dnes si v tutoriálu ukážeme jednu kolekci, která je chytřejší, než pole. Umožňuje totiž prvky libovolně přidávat a mazat.

Pojem kolekce jsme tu již zmínili. Je to struktura, do které můžeme ukládat více objektů. Kolekcí je v Javě velké množství, jsou uzpůsobeny na různé účely a můžeme s nimi zacházet různými způsoby. Proto jim je věnována celá sekce. Dosud známe pouze kolekci pole. V průběhu seriálu však budeme potřebovat něco chytřejšího, kam budeme moci jednoduše za běhu programu přidávat a mazat záznamy. Jistě by se nám hodilo si v paměti spravovat databázi nějakých objektů. Víme, že pole má konstantní velikost, což je daň za jeho vysokou rychlost. Nyní si představíme ArrayList, který můžeme již podle názvu chápat jako nadstavbu pole.

ArrayList

ArrayList je tzv. generická kolekce. Pojem genericita si plně vysvětlíme až u kolekcí, nyní nám bude stačit vědět, že při deklaraci ArrayListu specifikujeme datový typ objektů, které v něm budou uloženy. Začněme jednoduše a udělejme si ArrayList čísel, která budeme náhodně losovat.

Losování

Program se nás vždy zeptá, zda chceme losovat další číslo a to se přidá do ArrayListu. Pokud již nebudeme chtít losovat, program vypíše losovaná čísla, seřazená od nejmenšího po největší. Založme si nový projekt Losovani a vytvořme si třídu Losovac. Třída bude obsahovat ArrayList typu Integer, kde budou čísla uložena.

Narážíme na třídu Integer, která slouží k uložení celých čísel a v podstatě obaluje typ int. Do ArrayListu se totiž dají vkládat pouze objekty, tedy proměnné referenčního typu. Pro tyto účely existuje typ Integer. Ke každému primitivnímu typu v Javě existuje jeho referenční "obal", brzy si je uvedeme. ArrayList bude privátní a bude sloužit pouze jako interní úložiště dané třídy, aby se na něj zvenku nedalo přistupovat.

ArrayList deklarujeme takto:

ArrayList<Integer> cisla;

Datový typ píšeme u generických kolekcí do špičatých závorek. ArrayList je samozřejmě objekt, jako každý jiný. Stejně jako u pole a jiných objektů, i zde proměnnou před použitím inicializujeme:

ArrayList<Integer> cisla = new ArrayList<Integer>();

Všimněte si závorek, které značí konstruktor. Takovýto list tedy umístíme do naší třídy, spolu s náhodným generátorem Random. Pro práci s třídou ArrayList je třeba přidat import java.util.Arra­yList. V konstruktoru atributy inicializujeme:

import java.util.ArrayList;
import java.util.Random;

public class Losovac {
    private ArrayList<Integer> cisla;
    private Random random;

    public Losovac() {
        random = new Random();
        cisla = new ArrayList<Integer>();
    }

}
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Dále přidáme metody losuj() a vypis(), kde losuj() přidá do ArrayListu nové náhodné číslo a také ho vrátí jako návratovou hodnotu. vypis() vrátí textový řetězec pro vypsání. Ten bude obsahovat čísla z cisla, seřazená a oddělená mezerou.

Losování náhodného čísla již známe z dílu o hrací kostce, zde budeme vyhazovat čísla od 1 do 100. Číslo do ArrayListu přidáme pomocí metody add():

public int losuj() {
    Integer cislo = random.nextInt(100) + 1;
    cisla.add(cislo);
    return cislo;
}

Velmi jednoduché, že? Kolekce ArrayList je interně poměrně složitá a zatím se nebudeme zabývat tím, co se uvnitř děje. To je ostatně účel Javy, nabízet kvalitní a sofistikované komponenty, které se jednoduše používají.

Výpis čísel bude ještě snazší. K setřídění ArrayListu použijeme metodu sort ze třídy Collections, která list setřídí. Bude tedy potřeba import java.util.Collec­tions. Metoda nic nevrací, pouze ArrayList setřídí uvnitř.

public String vypis() {
    String s = "";
    Collections.sort(cisla);
    for (int i : cisla) {
        s += i + " ";
    }
    return s;
}

Hotovo.

Přesuňme se do main() a pomocí while cyklu umožněme uživateli ovládat objekt. Podobný program byla kalkulačka z prvních lekcích, kde jsme se v cyklu ptali, zda si uživatel přeje opakovat výpočet. Zde budeme postupovat totožně.

Ovládání bude pomocí možností 1, 2, 3 (losuj, vypiš, konec). Budeme je načítat pomocí sc.nextLine() jako String.

Scanner sc = new Scanner(System.in, "Windows-1250");
Losovac losovac = new Losovac();
System.out.println("Vítejte v programu losování.");
String volba = "0";
// hlavní cyklus
while (!(volba.equals("3"))) {
    // výpis možností
    System.out.println("1 - Losovat další číslo");
    System.out.println("2 - Vypsat čísla");
    System.out.println("3 - Konec");
    volba = sc.nextLine();
    System.out.println();
    // reakce na volbu
    switch (volba) {
        case "1":
            System.out.printf("Padlo číslo: %s\n", losovac.losuj());
            break;
        case "2":
            System.out.printf("Padla čísla: %s\n", losovac.vypis());
            break;
        case "3":
            System.out.println("Děkuji za použití programu");
            break;
        default:
            System.out.println("Neplatná volba, zadejte prosím znovu.");
            break;
    }
}

Nezapomeneme na import Scanner. Vlastně můžeme nechat řešení importů na NetBeans, stačí kliknout pravým tlačítkem a zvolit Fix imports, případně použít klávesovou zkratku Ctrl + Shift + I.

Průběh programu je z kódu dobře viditelný, nejprve nastavíme volbu na nějakou výchozí hodnotu, aby cyklus poprvé proběhl. Poté volbu načteme z klávesnice. String zpracujeme pomocí switche a provedeme příslušné akce. Pokud bylo zadáno něco jiného, pokryje to možnost default.

Konzolová aplikace
3 - Konec
1
Padlo číslo: 52
1 - Losovat další číslo
2 - Vypsat čísla
3 - Konec
1
Padlo číslo: 40
1 - Losovat další číslo
2 - Vypsat čísla
3 - Konec
1
Padlo číslo: 62
1 - Losovat další číslo
2 - Vypsat čísla
3 - Konec
2
Padla čísla: 2 6 7 7 8 8 9 9 10 10 12 14 17 19 19 21 23 25 25 27 27 27 28 28 28 30 30 31 32 33 33 35 35 36 36 36 37 38 38 40 41 42 42 42 44 45 45 45 45 45 48 51 52 52 53 55 56 56 56 57 58 58 59 61 62 66 68 68 71 72 73 73 74 76 82 83 84 84 85 87 88 88 89 90 90 91 93 94 98 98 98 99 100
1 - Losovat další číslo
2 - Vypsat čísla
3 - Konec

Vidíme, že můžeme stále přidávat nová a nová čísla. Máme mnohem větší možnosti, než s polem. Zároveň však můžeme s ArrayListem pracovat podobně, jako jsme pracovali s polem.

K přístupu můžeme využít metody get() a set(), ale pozor, prvek musí existovat. Zkusme si napsat následující kód:

ArrayList<String> l = new ArrayList<String>();
l.add("První");
System.out.println(l.get(0));
l.set(0, "První položka");
System.out.println(l.get(0));
l.set(1, "Druhá položka");  // vyhodí chybu

Vytvoříme si list Stringů. Přidáme položku "První" a poté vypíšeme položku na indexu 0. Vypíše se nám "První". Můžeme na ni samozřejmě i takto zapisovat. S druhou položkou na pozici 1 však již nemůžeme pracovat, protože jsme ji do listu nepřidali. U pole jsme zadali velikost a on všechny "přihrádky" (proměnné pod indexy) založil. Nyní velikost nezadáváme a "přihrádky" si přidáváme sami.

Podívejme se na ArrayList podrobněji a vypišme si metody, které jsou pro nás nyní zajímavé:

Konstruktory

Kromě prázdného ArrayListu můžeme List vytvořit i jako kopii z jiného listu, pole nebo jiné kolekce. Stačí kolekci předat do konstruktoru:

String[] poleStringu = {"První", "Druha", "Třetí"};
ArrayList<String> l = new ArrayList<String>(Arrays.asList(poleStringu));
System.out.println(l.get(2));

Kód výše vypíše "Třetí". Prvky pole se do nového listu zkopírují. Stejně můžeme předat i jiný ArrayList.

Metody na ArrayListu

  • size() - Funguje jako length na poli, vrací počet prvků v kolekci.
  • add(položka) - Metodu add() jsme si již vyzkoušeli, jako parametr bere položku, kterou vloží do listu.
  • addAll(kolekce) - Přidá do listu více položek, např. z pole.
  • clear() - Vymaže všechny položky v listu.
  • contains(položka) - Vrací true/false podle toho, zda ArrayList obsahuje předanou položku.
  • indexOf(položka) - Vrátí index prvního výskytu položky (jako u pole). Vrací -1 při neúspěchu.
  • lastIndexOf(po­ložka) - Vrací index posledního výskytu položky v Listu. Vrací -1 při neúspěchu.
  • remove(položka) - Vymaže první nalezenou položku.
  • removeAll(index, počet) - Vymaže daný počet prvků od zadaného indexu.
  • toArray() - Zkopíruje položky z ArrayListu do pole a to vrátí.

Další metody

Další metody a pro práci s listem najdeme ve třídě Collections. Jako parametr berou danou kolekci.

  • min() - Vrátí nejmenší prvek z kolekce.
  • max() - Vrátí největší prvek z kolekce.
  • reverse() - Obrátí list tak, že je první položka poslední a naopak. Metoda nic nevrací, změny se provedou v zadaném listu.
  • sort() - Sort již také známe, setřídí položky v listu. Metoda opět nic nevrací.

Vidíme, že kolekce ArrayList toho umí mnohem více, než pole. Největší výhodou je přidávání a mazání prvků. Daň ve výkonu je zanedbatelná. V sekci s kolekcemi zjistíme, že ArrayList má ještě další metody, ale zatím na to nemáme zkušenosti.

Program pro ukládání losovaných čísel byl zajímavý, ale jistě se nám bude v budoucnu hodit ukládat spíše plnohodnotné objekty, než čísla. V příští lekci, Datum a čas v Javě 8 - Vytváření a formátování, si uděláme pomocí ArrayListu databázi, bude to elektronický diář! :)


 

Stáhnout

Staženo 671x (22.32 kB)
Aplikace je včetně zdrojových kódů v jazyce java

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
25 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Předchozí článek
Gettery a settery v Javě
Všechny články v sekci
Objektově orientované programování v Javě
Miniatura
Následující článek
Cvičení k 11. lekci OOP v Javě
Aktivity (10)

 

 

Komentáře

Avatar
martinkobelka
Redaktor
Avatar
martinkobelka:3.4.2013 18:05

Jak můžu zjistit, kolik je v listu položek?

 
Odpovědět 3.4.2013 18:05
Avatar
Kit
Redaktor
Avatar
Odpovídá na martinkobelka
Kit:3.4.2013 18:08

Hned první metoda v seznamu: size()

Odpovědět 3.4.2013 18:08
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David
Redaktor
Avatar
David:3.4.2013 18:08

máš to napsané v metodách:
size() - Funguje jako length na poli, vrací počet prvků v kolekci.

Odpovědět  +1 3.4.2013 18:08
Nic néni nemožné!
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na martinkobelka
Petr Nymsa:3.4.2013 18:08

Že by

size() - Funguje jako length na poli, vrací počet prvků v kolekci.
Odpovědět 3.4.2013 18:08
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
Зайчик
Člen
Avatar
Odpovídá na martinkobelka
Зайчик:3.4.2013 18:09

UGBASQ! list.size();

Odpovědět 3.4.2013 18:09
Коммунизм для нашего будущего!
Avatar
Kit
Redaktor
Avatar
Kit:4.4.2013 14:16

Místo

ArrayList<Integer> cisla = new ArrayList<Integer>();

by se měla dávat přednost zápisu

List<Integer> cisla = new ArrayList<Integer>();

případně

Collection<Integer> cisla = new ArrayList<Integer>();

Programovat se má proti rozhraní, nikoli proti implementaci.

Odpovědět 4.4.2013 14:16
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
domino.turak
Člen
Avatar
domino.turak:15.6.2013 17:19

Mám otázku. Chcel by som si upevniť vedomosti ohľadom ArrayListu, pretože ten diár bol fakt strašne náročný a veľakrát som sa strácal čo vlastne odkazuje načo. Napadlo ma že si spravím Internetovú žiacku knižku,do ktorej budeme môcť pridávať žiakov, vyhľadávať ich, jednoducho niečo podobné ako bol ten diár. Avšak narazil som na jeden problém. Neviem konkrétnemu žiakovi priradiť známky. Dá sa to vôbec? Myslím to tak, že budem mať vytvorené x prvkové pole žiakov,a x polí so známkami týchto žiakov. Chcel som proste aby každý žiak mal vlastný ArrayList<Integer> "meno žiaka"=new ArrayList<>(). Urobil som si metódu pridajZnamku(String meno) a za "meno žiaka" som chcel dosadiť meno, avšak zahlásilo mi duplicate variable. Ako sa to dá spraviť?Ďakujem :)

Odpovědět 15.6.2013 17:19
"Never give up!"
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na domino.turak
David Čápka:15.6.2013 17:33

Ne, myšlenka více polí je špatně. Budeš mít objekt žák a ten v sobě bude mít jedno pole se svými známkami. Žáky dáš potom do ArrayListu. Je to stejné, jako u toho diáře. Pokud je to na tebe moc těžké, tak si udělej znovu seriál Objektově orientované programování v Javě, kde je to podrobně vysvětlováno.

Odpovědět 15.6.2013 17:33
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Kit
Redaktor
Avatar
Odpovídá na domino.turak
Kit:15.6.2013 19:40

Hlavně si promysli, jaký je rozdíl mezi polem a seznamem. Škola má seznam tříd, třída má seznam žáků, každý žák má seznam známek. Nikde nevidím pole.

Odpovědět 15.6.2013 19:40
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Benjibs
Člen
Avatar
Benjibs:24.7.2013 8:25

Nestačilo by pri tvorbe ArrayList-u použit diamant?
Alebo to tak nie je zámerne?

Odpovědět 24.7.2013 8:25
1 + 1 = 2
Avatar
vfsdfsdfdsf
Člen
Avatar
vfsdfsdfdsf:16.1.2014 11:21

Ahoj, mockrát díky za skvělý článek :) Škoda, že jsem o kolekcích nevěděl dřív, ušetřil bych si dost trápení když jsem zkoušel psát své jednoduché programy :D

Mám tři drobné dotazy:

1. Proč mi občas Scanner dělá to, že když zadám např. "3" (bez uvozovek), tak on to číslo jakoby přepíše a další System.out napíše hned místo toho čísla? Dělá mi to jen někdy asi tak 1 případ z 10.
Např. Tvá volba: Díky za použití programu
Zkoušel jsem i přímo zkopírovat kód odsud, se stejným výsledkem.

2. Jak je věrohodná metoda nextInt třídy Random? Z čeho vyvozuje čísla? Přidal jsem 100 čísel do ArrayListu a medián byl 88 o_O Vyhnul jsem se tomu, že bych zakládal více instancí... mám jen jednu pro celý program.

3. U té poznámky ke Konstruktorům (kopírování z pole) - nemá tam být ArrayList? Zkoušel jsem ten List<String> co to udělá, no ani se mi to nezkompilovalo :D

Každopádně mockrát díky :) Je to super

 
Odpovědět 16.1.2014 11:21
Avatar
Kit
Redaktor
Avatar
Kit:16.1.2014 12:03
  1. Zkus sc.nextLine() hned po scanu čísla.
  2. Udělej si statistiku a poznáš sám.
  3. Správně je skutečně
List<String> seznam = new ArrayList<String>(Arrays.asList(poleStringu));

i když často je možné použít jednodušší

List<String> seznam = Arrays.asList(poleStringu);

jen je potřeba dát pozor na tohle:

String[] pole = {"Adam", "Božena", "Cyril"};
List<String> seznam = Arrays.asList(pole);
System.out.println(seznam.get(2));
pole[2] = "David";
System.out.println(seznam.get(2));

protože to proti předpokladům vypíše

Cyril
David

a to může být v některých situacích docela nepříjemné. Nevytváří se totiž nový seznam, ale jen pohled na pole tak, aby vypadalo jako seznam.

Editováno 16.1.2014 12:06
Odpovědět  +2 16.1.2014 12:03
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
vfsdfsdfdsf
Člen
Avatar
Odpovídá na Kit
vfsdfsdfdsf:16.1.2014 13:38
  1. Pomohlo to :) Je to asi něco podobné, jako s prázdným cin.get() u C++... ono je to dost složité pochopit, jak to funguje vnitřně, takže se tím moc zabývat teď nebudu... na to zatím nemám hlavu :D
  2. Zkusil jsem 5000 iterací a medián byl 62 a potom 54, to už celkem jde :)
  3. Mám ten příklad s Adamem, Boženou a Cyrilem chápat tak, že je to něco podobného, jako když přiřadíme jednu referenční proměnnou druhé referenční proměnné? Obě pak odkazují na tu samou instanci...

Jinak, kdy je tedy vhodné použít vlevo List a kdy ArrayList? Výše si psal, cituji:

Programovat se má proti rozhraní, nikoli proti implementaci.

Vůbec nechápu, jak si to myslel...
A ještě bych se rád zeptal: v dalším článku (diář) je toto:

private ArrayList<Zaznam> zaznamy = new ArrayList<>();

U instance není uveden datový typ... ale v ref. proměnné je. To se může? Chápu to tak, že instance je rozšířená na všechny dat. typy a tudíž nemůže být přiřazena do ref. proměnné, která je zúžená jen na dat. typ záznam.

Je pravda, že v tom začínám mít docela guláš, kdy co použít :D

 
Odpovědět 16.1.2014 13:38
Avatar
Kit
Redaktor
Avatar
Odpovídá na vfsdfsdfdsf
Kit:16.1.2014 13:47

List je rozhraní (interface), ArrayList je jedna z jeho implementací. Pokud jiná část aplikace bude vyžadovat v rozhraní List, tak jí v daném případě bude jedno, zda to bude ArrayList nebo LinkedList. Budou zaměnitelné.

Jak vidíš, Java snese hodně. Proto si na tyhle vlastnosti před použitím píši testy, které ve výsledné aplikaci nechávám, abych si například při změně běhového prostředí mohl rychle ověřit, že to stále funguje.

Odpovědět  +1 16.1.2014 13:47
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Tom Barbořík:23.11.2014 12:58

Máš chybu v příkladu. U struktury switch / case se můžou používat jenom primitivní dat. typy a ty tu máš String. Vyřešil jsem to získáním 1. znaku ze stringu metodou charAt(0), ale je potřeba to ještě ošetřit v případě, že není zadaný žádný znak.

 
Odpovědět  -1 23.11.2014 12:58
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Tom Barbořík
David Čápka:23.11.2014 14:11

Neni to chyba, mas starou verzi Javy, switch umí stringy myslím od sedmicky a už ta je dost stara :)

Odpovědět  +1 23.11.2014 14:11
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Odpovídá na David Čápka
Tom Barbořík:24.11.2014 20:40

Javu mám osmičku. To by mi pak nešlo použít ani localdatetime.
Problém byl v ide. Vyřešil jsem to podle tohoto návodu: http://stackoverflow.com/…1443/3237756

 
Odpovědět 24.11.2014 20:40
Avatar
Ten Zdeněk :21.3.2015 20:26

nechápu tento blok:

for (int i : cisla)
                s += i + " ";

Přijde mi divná syntaxe cyklu for(). Nevím jestli jsem blbý nebo je to špatně napsané. Přečetl jsem si znovu cykly, ale takový zápis jsem nenašel.
Jinak super článek, Díky. :)

 
Odpovědět 21.3.2015 20:26
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Ten Zdeněk
Jan Vargovský:21.3.2015 20:56
https://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html

Kdybys to nějak nezchroustal, tka ti tu napíšu nějaký výcuc :)

 
Odpovědět  +1 21.3.2015 20:56
Avatar
roman64
Redaktor
Avatar
roman64:26.6.2015 9:36

Poznámka k příspěvku KIT z 16.1.2014. Pokud změníš prvek arrayList, který se předtím "zkopíroval" (odkazuje)z pole, tak se změna prvku nepromítne do pole (opačne to funguje - jak uvádíš).

http://www.itnetwork.cz/dev-lighter/614

Odpovědět  -1 26.6.2015 9:36
Definice šílenství je dělat stejnou věc znovu a znovu a očekávat jiné výsledky.“ Albert Einstein.
Avatar
Michal Remišovský:8.5.2016 19:07
public int losuj()
{
        Integer cislo = random.nextInt(100) + 1;
        cisla.add(cislo);
        return cislo;
}

V metodě losuj má být 99 místo 100:

Integer cislo = random.nextInt(99) + 1;
 
Odpovědět  -2 8.5.2016 19:07
Avatar
Nezmar Hydra
Člen
Avatar
Nezmar Hydra:19.6.2016 0:33

Proč mi nefunguje ve třídě Losovac:
public Mazej()
{
cisla.clear();

}

musim to napsat
public String Mazej()
{
String d = ""
cisla.clear();
return d
}
?????????????­?????????????????
Chci jen zavolat metodu Mazej nepotřebuju vracet žádné hodnoty. Jak to mám napsat "gramaticky" správně?

 
Odpovědět 19.6.2016 0:33
Avatar
Erik Báča
Člen
Avatar
Odpovídá na Nezmar Hydra
Erik Báča:19.6.2016 0:47

Nepřeskakuj předchozí tutoriály, název metody se píše s malým písmenem a když metoda nemá nic vracet, tak to má vypadat takhle:

public void mazej() {
}

Ale to už bys měl dávno vědět, když se učíš arraylist

Odpovědět 19.6.2016 0:47
Když mi dáš mínus, napiš proč!
Avatar
Nezmar Hydra
Člen
Avatar
Nezmar Hydra:19.6.2016 3:32

Já nepřeskakuju. Jen si prd pamatuju. ......... Omluva a díky.

 
Odpovědět 19.6.2016 3:32
Avatar
Erik Báča
Člen
Avatar
Odpovídá na Nezmar Hydra
Erik Báča:19.6.2016 11:36

Já si proto to nejdůležitějšího píšu do sešitu, když si to napíšeš rukou do sešitu tak to určitě nezapomeneš a i kdyby, tak se do něj můžeš kouknout ;).

Odpovědět 19.6.2016 11:36
Když mi dáš mínus, napiš proč!
Avatar
Nezmar Hydra
Člen
Avatar
Nezmar Hydra:19.6.2016 23:09

Já si psal poznáky do ukázkovejch programů....... . Sešit má něco do sebe :-)

Editováno 19.6.2016 23:09
 
Odpovědět 19.6.2016 23:09
Avatar
Vít Pelc
Člen
Avatar
Vít Pelc:21.11.2016 16:53

Mám menší problém.
Dělal jsem kód podle vzoru výše, avšak při psuštění hlásí chybu, přičemž odkazuje na určité řádky ve zdrojáku. Problémem je, že nemůžu přijít na to, na jakou chybu mě odkazuje.
Poraďte prosím

 
Odpovědět 21.11.2016 16:53
Avatar
Odpovídá na Vít Pelc
Lubomír Jahn:28.11.2016 23:16

Z toho co vidím můžu vyvodit jedině to že ti to vyhazuje NullPointerEx­ception protože voláš metodu losuj() na objektu, který buď neexistuje nebo má hodnotu null. Pokud ti tam nechybí vytvoření objektu Lottery l = new Lottery(); tak nevím co by mohlo být zdrojem chyby.

Editováno 28.11.2016 23:19
 
Odpovědět 28.11.2016 23:16
Avatar
Lubomír Jahn:28.11.2016 23:20

Z toho co vidím můžu vyvodit jedině to že ti to vyhazuje NullPointerEx­ception protože voláš metodu losuj() na objektu, který buď neexistuje nebo má hodnotu null. Pokud ti tam nechybí vytvoření objektu Losovac l = new Losovac(); tak nevím co by mohlo být zdrojem chyby.

 
Odpovědět 28.11.2016 23:20
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Vít Pelc
Člen
Avatar
Odpovídá na Lubomír Jahn
Vít Pelc:14.12.2016 17:47

Kontroloval jsem si to, ale podle teorie tam nemám žádnou chybu. Vytvoření instance Losovac() tam mám, což mě zaráží ještě víc. Ptal jsem se na to i učitele, kterého máme na Javu, ale taky bohužel neví.

 
Odpovědět 14.12.2016 17:47
Avatar
Odpovídá na Vít Pelc
Erik Šťastný:14.12.2016 17:51

Mám návrh co kdyby jsi ten problém rovnou napsal celý popřípadě postnul kód na místo screenshotu, kde toho moc není a říkání, jak to ani tvůj učitel neví :)

 
Odpovědět 14.12.2016 17:51
Avatar
Odpovídá na Vít Pelc
Libor Šimo (libcosenior):14.12.2016 18:11

Stiahol si si vzorovy kod pod clankom a porovnal s tym svojim?

Editováno 14.12.2016 18:12
Odpovědět 14.12.2016 18:11
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Vít Pelc
Člen
Avatar
Vít Pelc:20.12.2016 17:30

Hlavní třída s metodou main

package arraylist;


import java.util.Scanner;
public class Arraylist {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Losovac l = new Losovac();
        String volba="0";

        while(!(volba.equals("3")))
        {
        System.out.println("Co si přejete provést za akci?: ");
        System.out.println("1. : Losovat číslo ");
        System.out.println("2. : Vypsat čísla ");
        System.out.println("3. : Konec ");
        volba = sc.nextLine();
        System.out.println();
        switch (volba)
            {
            case "1":
                 System.out.printf("Padlo číslo: %s\n ", l.losuj());
                break;
            case "2":
                System.out.printf("Padla čísla: %s\n ", l.vypis());
                break;
            case "3":
                System.out.println("Děkuji za použití programu.");
                break;
            default:
                System.out.println("Špatná volba!");
                break;
            }
        System.out.println();
        }
    }

}

třída Losovač

package arraylist;


import java.util.ArrayList;
import java.util.Random;
import java.util.Collections;

public class Losovac {
    private ArrayList<Integer> cisla;
    private Random random;

    private void Losovac()
    {
     this.random = new Random();
    this.cisla = new ArrayList<Integer>();
    }

    public int losuj()
    {
        int cislo = random.nextInt(99)+1;
        cisla.add(cislo);
        return cislo;
    }

    public String vypis()
    {
        String s = " ";
        Collections.sort(cisla);
        for (int i : cisla)
        {
            s += i + " ";
        }
        return s;
    }

}
 
Odpovědět 20.12.2016 17:30
Avatar
Petr Štechmüller
Překladatel
Avatar
Odpovídá na Vít Pelc
Petr Štechmüller:20.12.2016 18:31

Ahoj, z jakého důvodu máš ve třídě Losovac privátní konstruktor? To by asi byt nemělo...

edit: ty vůbec nemáš definovány konstruktor

Editováno 20.12.2016 18:31
Odpovědět  +1 20.12.2016 18:31
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Vít Pelc
Člen
Avatar
Odpovídá na Petr Štechmüller
Vít Pelc:23.12.2016 19:18

Nojo, toho privátního konstruktoru jsem si ani nevšiml. Díky za upozornění. To byla ta zásadní chyba, teď už to jede jako na drátkách :). Chyba z nepozornosti, ještě se mám co učit.

 
Odpovědět 23.12.2016 19:18
Avatar
Petr Štechmüller
Překladatel
Avatar
Odpovídá na Vít Pelc
Petr Štechmüller:23.12.2016 19:23

Jenže chyba byla někde jinde. Ty jsi měl definovanou metodu takto:

private void Losovac() {}

problém byl v tom, že tohle není konstruktor, ale obyčejná privátní metoda bez návratové hodnoty.

Odpovědět 23.12.2016 19:23
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Vít Pelc
Člen
Avatar
Odpovídá na Petr Štechmüller
Vít Pelc:23.12.2016 19:25

Jo, já vím. Už ani nevím, proč jsem to tam tak pitomě napsal :D. Byl jsem asi myšlenkama někde jinde.
Každopádně už mám konstruktor definovaný správně, a to:

public Losovac() { }
Editováno 23.12.2016 19:25
 
Odpovědět  +1 23.12.2016 19:25
Avatar
Mirka Baranová:15.1.2017 22:07
  1. otázka: Je metoda: removeAll(index, počet) - "Vymaže daný počet prvků od zadaného indexu." správně? Mi to funguje jen takto: removeAll(kolekce) - vymaže celou kolekci z listu.
  2. otázka: Jak se používá metoda toArray()? Když si založím ArrayList "rodina" jako list jmen a nechám si vypsat System.out.prin­tln(rodina.to­Array()); výstup je: [Ljava.lang.Ob­ject;@15db9742
Odpovědět 15.1.2017 22:07
Pro člověka, který je plný touhy, není nic nemožné.
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Mirka Baranová
pocitac770:16.1.2017 0:10
  1. Zkoušel jsem něco k tomu dohledat, nic jsem nenašel, vypadá to na chybu ve článku. Možná autor myslel na metodu .subList(), která má stejné parametry, ale vytváří nový list, obsahující právě tyto prvky. .removeAll() opravdu funguje jak popisuješ.
  2. .toArray() vrací pole, a to doslava, to, co se snažíš je vypsání reprezentace pole, a základní Stringová reprezentace je co? Hash. Viz přetěžování metod, .toString apod. Je to to samé, jako bys napsala
ArrayList<Neco> a = nevimCoMamTedSakraVymysletJePozdeVecer();
Neco[] pole = a.toArray();
System.out.pritnln(pole); //špatně
System.out.pritnln(Arrays.toString(pole); //správně
Editováno 16.1.2017 0:11
 
Odpovědět 16.1.2017 0:10
Avatar
Mirka Baranová:21.1.2017 18:44

2. Jo, chápu, ale mi šlo o to, že mi nejdou do pole přidat prvky z toho ArrayListu. V tvém příkladu 2. řádek nebo můj příklad:

ArrayList<String> rodina = new ArrayList<String>();
rodina.add("Alena");
rodina.add("Petr");
String[] jmena = rodina.toArray(); // tohle nefunguje
Odpovědět 21.1.2017 18:44
Pro člověka, který je plný touhy, není nic nemožné.
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Mirka Baranová
pocitac770:21.1.2017 20:03

Tak jsem to vyzkoušel, problém je ten, že to vrací pole výhradně Objectů. To znamená, že to jde vyřešit dvěmi cestami...

  1. Postupně jednotlivé Objecty protypovávat na Stringy, pracovat s nimi, a potenciálně je neskládat do nového pole
  2. Použít v metodě jako parametr pole, které má stený typ (v tomto případě String), pokud bude délka stejná, jako délka listu, pak se rovnou do něj všechny prvky doplní, v opačném případě si to pouze vezme typ a vrátí nové pole. Toho jde využít, když máš již nějaké jiné pole vytvořené a chceš ho znovu použít na toto, pak můžeš doplnit do parametru přímo instanci a vynechat "doplňovací" část před rovnítkem
ArrayList<String> list = new ArrayList<String>();
list.add("Jedna");
list.add("Dva");
//1)
Object[] pole1 = list.toArray();
Sring[] pole2 = new String[pole1.length];
for(int i = 0; i < pole1.length; i++){
        System.out.println((String)pole1[i]);
        pole2[i] = (String)pole1[i];
}
//2.1)
String[] pole3 = list.toArray(new String[list.size()]);
for(String s : pole3){
        System.out.println(s);
}
//2.2)
String[] pole4 = new String[list.size()];
list.toArray(pole4);
for(String s : pole4){
        System.out.println(s);
}
Editováno 21.1.2017 20:04
 
Odpovědět 21.1.2017 20:03
Avatar
Lesní Muž
Člen
Avatar
Odpovídá na Michal Remišovský
Lesní Muž:3.3.2017 18:53

Nene, takhle ti to pojede od 0 do 99.

 
Odpovědět 3.3.2017 18:53
Avatar
Lesní Muž
Člen
Avatar
Lesní Muž:4.3.2017 19:36

Nenašel by se tady nějaký bůh, který by mi vysvětlil tohle, prosím?

String[] poleStringu = {"První", "Druha", "Třetí"};
List<String> l = new ArrayList<String>(Arrays.asList(poleStringu)); //tento řádek prostě nepobírám
System.out.println(l.get(2));
 
Odpovědět 4.3.2017 19:36
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Lesní Muž
David Čápka:4.3.2017 20:09

Arrays.asList() převede zadané pole na kolekci s rozhraním List, je to potřeba k tomu, aby se mohlo předat při vytváření ArrayListu. Ten řádek nedělá nic jiného, než že vytváří nový ArrayList l, do kterého rovnou vloží prvky z poleStringu.

Odpovědět  +1 4.3.2017 20:09
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Lesní Muž
Člen
Avatar
Odpovídá na David Čápka
Lesní Muž:6.3.2017 18:56

Děkuji mnohokrát, já v tom hledal něco složitějšího a to "asList" mě zmátlo. Hned jdu shánět lidi do kultu Davida Čápky!

Editováno 6.3.2017 18:57
 
Odpovědět 6.3.2017 18:56
Avatar
Jakub Bómíček Bohm:9.3.2018 17:48

Věděl by jste někdo, jak je to se Stackem a Heapem u arraylistu ? Třeba pole má v zásobníku referenci na reálné pole v haldě, kde jsou za sebou prvky primitivního typu. O objektů tam jsou teda ještě reference na samotný objekty, protože ty jsou rozházený v haldě. Když do arraylistu integerů přidám nějaké číslo, jak je to s tou pamětí ?

 
Odpovědět 9.3.2018 17:48
Avatar
Jakub Krsička:11.10.2018 1:31

Zdarec, prosím vás mám dotaz už jsem si několikrat všiml problému s cyklem While, aktuálně jsem zpracovával test který byl ve statice, že si objekty dám do arrayListu, jenomže. Pokud switchi nastavím case 4: kde je napsáno, aby se nesplnila podmínka pro další cyklus tak stejně kus kodu v cyklu probehne.... Nevím co s tím. Zde je kod budu rád za rady.

package teststatika1;
import java.util.Scanner;
import java.util.ArrayList;
/**
 *
 * @author krsmen...
 */
public class TestCukrarna {



    ArrayList<Cukrovi> kolekceCukrovi = new ArrayList<Cukrovi>();
    Scanner sc = new Scanner (System.in, "UTF-8");
    int pocetVPoli = 0;

    public void rozhrani()
    {
        vytvoreniCukrovi();
        vypis();
    }

    private void vytvoreniCukrovi()
    {


       boolean konec = true;
       while(konec)
       {
        System.out.println("Vyberte volbu které cukroví chcete vytvořit:\n 1- bananove\n 2- jahodove\n 3- cokoladove\n 4- ukončit podprogram");
        int volba = Integer.parseInt(sc.nextLine());
        System.out.println("Zadejte prosím kolik kusů chcete vytvořit:");
        int pocet = Integer.parseInt(sc.nextLine());
        switch(volba)
        {
            case 1:
            for (int i = 0; i < pocet; i++)
            {
                   kolekceCukrovi.add(TovarnaNaCukrovi.vytvorBananove());
            }
            System.out.println("Bylo "+ pocet + " kusů banánového cukroví");
            break;

            case 2:
            for (int i = 0; i < pocet; i++)
            {
                   kolekceCukrovi.add(TovarnaNaCukrovi.vytvorJahodove());
            }
            System.out.println("Bylo "+ pocet + " kusů jahodového cukroví");
            break;

            case 3:
            for (int i = 0; i < pocet; i++)
            {
                   kolekceCukrovi.add(TovarnaNaCukrovi.vytvorCokoladove());
            }
            System.out.println("Bylo "+ pocet + " kusů cokoladoveho cukroví");
            break;

            case 4:
            System.out.println("Ukončuji podprogram vytváření cukroví");
            konec = false;
            break;

            default:
            System.out.println("Zadali jste špatnou volbu, prosím zadejte znovu.");
            break;
        }
      }
    }
    public void vypis()
    {
        for(int i = 0; i < this.kolekceCukrovi.size();i++)
        {
            System.out.println(kolekceCukrovi.get(i).toString());
        }
    }

}
 
Odpovědět 11.10.2018 1:31
Avatar
Odpovídá na Jakub Krsička
Matúš Olejník:11.10.2018 8:24

A aký kus kódu konkrétne myslíš? Ak je to toto

System.out.println("Zadejte prosím kolik kusů chcete vytvořit:");
int pocet = Integer.parseInt(sc.nextLine());

tak je logické že to zbehne ešte pred ukončením cyklu pretože vyhodnocovanie aká bola zadaná voľba je až za tým.
Môžeš logiku z case 4 vytiahnuť do ifu hneď za načítanie voľby, kde teda ak zistíš že voľba je 4 tak ukončíš cyklus bez toho aby sa vyhodnocoval switch :) Rovnako default case sa ti vykoná až po tom čo zadáš pocet hoci voľba bola mimo dovolených hodnôt.

Odpovědět 11.10.2018 8:24
/* I am not sure why this works but it fixes the problem */
Avatar
Odpovídá na Matúš Olejník
Jakub Krsička:11.10.2018 10:15

Ano tomu samozrejme rozumím, jenomže pokud mi vypíše println zadejte hodnotu, já zadám 4 potvrdim enter. Tak i přes to, že vstupní podmínka po ukončení cyklu nesouhlasí tak se mi spustí println, i scanner a další cyklus se ukončí až po těchto řádcích.

 
Odpovědět 11.10.2018 10:15
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Jakub Krsička
pocitac770:12.10.2018 13:32

Tvůj problém je ten, že proběhne kód za tímto načtením, a teprv pak se to dostane ke switchi, po čemž skončí cyklus. Máš dvě možnosti

  1. To druhé načtení z konzole dát do podmínky, tzn pokud volba není 4, tak má smysl načítat počet, jinak přejdeš dále do switche, takto to můžeš použít i do budoucna na jiné volby, které taktéž nebudou vyžadovat počet
  2. použít v cyklu řádek "break;", ten samý, co znáš ze switche, ukončí to okamžitě právě probíhající cyklus, tímpádem rovnou skočíš na rádek za while cyklem, kde můžeš mít ono rozloučení programu
 
Odpovědět 12.10.2018 13:32
Avatar
Odpovídá na pocitac770
Jakub Krsička:13.10.2018 2:52

Díky za info, jak budu u PC tak to zkusím, to takhle cyklus while probíhá normálně a vždy ?

 
Odpovědět 13.10.2018 2:52
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Jakub Krsička
pocitac770:14.10.2018 8:34

Každý cyklus má svá pravidla, jako například while cyklus, který se OPAKUJE, dokud je splněna podmínka. Důležité je ono opakuje, tzn, pokud je na začátku cyklu podmínka splněna, tak celý proběhne, kontrola probíhá opět když má začít nové opakování. Onen příkaz break je jenom taková pomůcka, zadní vrátka dalo by se říct, díky které můžeš ty pravidla "porušit". Stejně tak příkaz "continue;", který dělá to samé co "break;", ale narozdíl od něj neukončí cyklus, pouze ukončí ono opakování, a cyklus pokračuje jako by již program došel na konec bloku. Zjednodušeně, přeskočí zbytek kódu v cyklu a vrátí se zpět na začátek.

 
Odpovědět 14.10.2018 8:34
Avatar
Jakub Krsička:16. března 17:40

zdravim potraboval bych znova radu s arraylistem.... chyba:

Exception in thread "main" java.lang.NullPointerException
        at databazefno.Databaze.pridatUzivatele(Databaze.java:38)
        at databazefno.Rozhrani.pridejTestUzivatele(Rozhrani.java:81)
        at databazefno.Rozhrani.spustitRozhrani(Rozhrani.java:20)
        at databazefno.DatabazeFNO.main(DatabazeFNO.java:19)

Rozhrani:

private void pridejTestUzivatele()
    {
        String [] poleJmen = {"Jakub","Veronika","Tobias","Pavel","Tomáš"};
        String [] poleLoginu = {"jak","ver","tob","pav","tom"};
        String heslo = "heslojeveslo";
        int [] poleVolba = {1,2,2,3,1};
        for (int i = 0; i < poleJmen.length; i++)
        {
            databaze.pridatUzivatele(poleLoginu[i], heslo, poleJmen[i], poleVolba[i]);//TADY TO PÍŠE CHYBU
        }
    }

Databaze:
ArrayList v databazi:

private ArrayList <Sestra> uzivatele;
private ArrayList <Pacienti> pacienti;
private int indexPac = -1;
private int indexUz = 0;
private boolean prihlaseny =false;
private String zprava = "";
private int typUzivatele;
public void pridatUzivatele (String login, String heslo, String jmeno, int volba)
{

    switch(volba)
    {
        case 1:
            Sestra s = new Sestra (login,heslo,jmeno);
            uzivatele.add(s);//TADY TO PÍŠE CHYBU
            zprava = String.format("Sestra byla přidána login: %s heslo: %s ", login,heslo);
            break;
        case 2:
            uzivatele.add(new Doktor(login,heslo,jmeno));
            zprava = String.format("Doktor byl přidán login: %s heslo: %s ", login,heslo);
            break;
        case 3:
            uzivatele.add(new Administrator(login,heslo,jmeno));
            zprava = String.format("Administrator byla přidána login: %s heslo: %s ", login,heslo);
            break;

    }

}

Sestra:

protected String login = "";
protected String jmeno = "";
protected String heslo = "";
private static int minimalniDelkaHesla = 6;
protected boolean prihlaseny = false;
private String typ = "sestra";



public Sestra (String login, String heslo, String jmeno)
{
    this.login = login;
    this.heslo = heslo;
    this.jmeno = jmeno;

}
 
Odpovědět 16. března 17:40
Avatar
Odpovídá na Jakub Krsička
Matúš Olejník:16. března 17:48

Nemáš inicializovaný List uzivatele. Tak ako inicializuješ iné objekty napr. Sestra s = new Sestra(); tak musíš niekde inicializovať aj ArrayList, uzivatele = new ArrayList(); pred tým ako budeš volať uzivatele.add(s) atď.

Editováno 16. března 17:48
Odpovědět 16. března 17:48
/* I am not sure why this works but it fixes the problem */
Avatar
Odpovídá na Matúš Olejník
Jakub Krsička:16. března 18:41

Jasně úplně jsem na to klasicky zapomněl a pak u toho sedím dvě hodiny a hledám chybu. :-D

 
Odpovědět 16. března 18:41
Avatar
Roman Harna
Člen
Avatar
Roman Harna:27. května 18:47

package alprog;
import java.util.Arrays;
import java.util.Arra­yList;

public class ALprog {

public static void main(String[] args) {

String[] poleStringu = {"První", "Druha", "Třetí"};
ArrayList<String> l = new ArrayList<Strin­g>(Arrays.asLis­t(poleStringu));
System.out.prin­tln(l.get(2));
String[] poleStringu2 = {"Ahoj", "Nazdar", "Cus"};
ArrayList<String> 2 = new ArrayList<Strin­g>(Arrays.asLis­t(poleStringu2));
System.out.prin­tln(2.get(2));
}

}

predposlední radek chyba - not a statement ";" expected
posledni radek: ")" a ";" expected

Nechapu, muze mi to nekdo vysvetlit??

 
Odpovědět 27. května 18:47
Avatar
Roman Harna
Člen
Avatar
Odpovídá na Roman Harna
Roman Harna:27. května 18:51

Uz to vim ta 2 je spatne :-###

 
Odpovědět 27. května 18:51
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 57 zpráv z 57.