NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
Avatar
Patrik Marýška:24.10.2017 1:14

Ahoj,

mohl bych vás poprosit o vysvětlení té poslední metody v tom zdrojáku (public static Contact createContact...) a jak to funguje a co se vlastně konkrétně vrací z té metody?

import java.util.ArrayList;

public class Contact {
    private String name;
    private String phoneNumber;

    public Contact(String name, String phoneNumber) {
        this.name = name;
        this.phoneNumber = phoneNumber;
    }

    public String getName() {
        return name;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public static Contact createContact(String name, String phoneNumber){
        return new Contact(name, phoneNumber);
    }

}

a potom ještě jeden dotaz:

private ArrayList<Contact> myContacts;

Do toho Arraylistu, když je to takto zapsané, tak se ukládá konkrétně co? Ta celá třída?

Mockrát děkuji

 
Odpovědět
24.10.2017 1:14
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:24.10.2017 9:01

Ano, do kolekce ukládáš objekty. V tom se kolekce liší od pole. Do pole vkládáš konkrétní (finální) hodnoty.

Jinak k té první otázce - podle názvu metody jde o nezdařeného singletona. Metoda vrací novou instanci třídy Contact.
Defakto v tomto případě je to to samé, pokud bys zavolal konstruktor této třídy.

public class Contact {

        public Contact() {  // <-- tady je konstruktor

        }
}

a v tomhle případě máš jedno, zda-li voláš novou instanci konstruktoru:

Contact contact = new Contact();

nebo to máš ve statické metodě, která vytvoří a vrátí novou instanci konstruktoru:

public static Contact nejakaMetoda() {
        return new Contact();
}

Normálně je v tom několik rozdílů, ale tady v tomto konkrétním případě je to fakt jedno.
Za jiných okolností platí:

  • u návratových metod se používá zavedená konvence slovíčka getXXXX() (proto se jim říká gettery)
  • pokud nějaká statická metoda vytváří instanci, můžeme tak pracovat ve statických blocích a před vytvořením samotné instance ještě jakkoliv nastavit potřebné atributy atd.
  • soudím, že tato metoda (podle názvu) je právě pouze na vytváření instance. Hodně často chceme, aby se vytvořila v jednom procesu pouze jediná instance této třídy (případně určitý počet instancí). Takové třídě se pak říká jedináček - singleton. To bys musel ale do té metody přidat ještě podmínku:
private static Contact contact;

public static Contact createContact(String name, String phoneNumber){
        if(contact == null) {
                contact = new Contact(name, phoneNumber);
        }
        return contact;
    }

Ale toto s dotazem nesouvisí:) jen ukázka, proč to třeba někdo takhle separuje do statické metody a nevytváří instance klasickým způsobem.

Nahoru Odpovědět
24.10.2017 9:01
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Lubor Pešek
David Hartinger:24.10.2017 9:57

Proč bys nemohl do pole ukládat objekty? Rozdíl mezi seznamem (listem) a polem je ten, že do pole nemůžeš přidávat další prvky nebo je mazat. Není to nezdařilý Singleton, ale úplně normální Factory method, přečti si návrhové vzory pro vytváření - https://www.itnetwork.cz/…ro-vytvareni Je pravda, že je tam trochu k ničemu, když má ty samé parametry jako má konstruktor.

Editováno 24.10.2017 9:57
Nahoru Odpovědět
24.10.2017 9:57
New kid back on the block with a R.I.P
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na David Hartinger
Lubor Pešek:24.10.2017 10:45

Jo máš recht, že to jde. Ono taky jde, že nemusíš vytvářet metody ani jakoukoli strukturu programu, ale všechno narveš do jedné metody a použiješ tisíc podmínek.
Ale myslel jsem, (a popravdě proto tyto stránky propaguju) že právě tento portál je proto, abychom radili všem, jak psát programy trošku na nějaké úrovni. Ale jestli se tady budeme bavit, jak programovat strukturovaně v Javě, tak sem přidejte obsáhlý tutorial pro programování v jedničkách a nulách-.-
Osobně nevidím smysl, proč by někdo do pole rval objekty. Když už používám pole, tak právě proto, abych urychlil běh programu. Přece jen je rychlejší, když s velkým počtem dat pracuju s primitivním datovým typem než s objektovými. Už jen kvůli uložišti.
Navíc jsi to sám řekl - pole je konečný seznam, ze kterého můžeš jen číst případně přepisovat index, ale snad uznáš, že je dobré, když máš možnost objekt v budoucnu celý smazat (nebo zahodit). I když můžeš nastavit hodnotu na null, pořád by sis v poli pamatoval nějakou referenci, i když na null.
Je to věc názoru ok, ale když tak mi sem postni prosím příklad, kdy je doopravdy skutečně výhodnější narvat objekty do pole než do kolekce.

S tou factory method máš pravdu. Já jsem to používal vždy jen tak (uznávám moje chyba, že jsem si to spojil hned od začátku tak, že to patří k sobě). Znám to, ale nikdy jsem to nepoužil separátně, ale to je chyba u mě, ne, že by to tak mělo být:) takže co se tohoto týče skláním uši a uznávám, že máš pravdu

Nahoru Odpovědět
24.10.2017 10:45
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na Lubor Pešek
gcx11:24.10.2017 13:00

U generických kolekcí primitivních typů máš ten problém, že je musíš boxovat/unboxovat, pokud jsi myslel toto. Ale třídy v Javě jsou referenční datové typy, takže tam boxing/unoxing není problém.

V tom případě je výhodnější použít ArrayList, než obyčejné pole, které ten ArrayList stejně používá vnitřně, viz http://hg.openjdk.java.net/…rayList.java. Navíc se automaticky zvětšuje/změnšuje velikost pole uvnitř.

 
Nahoru Odpovědět
24.10.2017 13:00
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na Patrik Marýška
gcx11:24.10.2017 13:24

A odpověď na druhý dotaz - normálně by sis mohl ukládat hodnoty stejného typu třeba do pole:

Contact[] myContacts;

ale s tím pak máš problém, že tam nemůžeš přidávat nové prvky, pokud budeš chtít používat jenom část pole, abys tam mohl něco přidávat, tak si musíš pamatovat počet prvků a navíc Ti pak stejně nemusí stačit jeho velikost.

Proto to můžeš obalit třídou, která se o toto bude starat a umožní Ti vkládání/mazání bez toho, aniž by ses musel starat o to, jak to funguje unvitř.

ContactArrayList myContacts;

A pak dojdeš k tomu, že bys třeba to samé potřeboval pro Phone, takže si vyrobíš podobnou třídu PhoneArrayList. Ale budeš v tom mít hodně podobný kód.

Proto přišla generika, kde máš nějakou třídu a tu můžeš specializovat na nějaký typ.

Třeba

ArrayList<Contact> myContacts;

kde to Contact ve špičatých závorkách specifikuje typ, na který se to specializuje. V tomto případě to znamená, že tam chceš ukládat instance od té třídy:

ArrayList<Contact> myContacts = new ArrayList<>();
myContacts.add(new Contact(...))
 
Nahoru Odpovědět
24.10.2017 13:24
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 6 zpráv z 6.