Programování v jazyku Java (9) - Pole II
Toto je první článek seriálu o programování v Javě, který navazuje na původní seriál Petra Hatiny, přerušený loni v září. Budeme se zabývat funkcemi, které nám
usnadňují manipulace s poli a vykonávají za nás nepříjemnou "černou" práci.
25.2.2005 15:00 |
Lukáš Jelínek
| Články autora
| přečteno 57664×
Využití třídy System
Kopírování prvků polí
Třída java.lang.System obsahuje metodu arraycopy() , která
umí zkopírovat prvky z jednoho pole do jiného. Lze kopírovat libovolný
počet prvků pole, nesmíme však samozřejmě "vyběhnout" mimo meze některého
z polí. Kopírovat lze i v rámci téhož pole, zdrojový a cílový úsek se
mohou překrývat (vnitřně to funguje tak, že se kopíruje do dočasného pole a pak
zpět do toho původního). Prvky pole mohou být jak primitivní, tak referenční
(objektové) typy (kopírují se samozřejmě jen odkazy, instance zůstavají
stejné).
Následující příklad ukazuje zkopírování části pole čísel typu double
do jiného takového pole (kopíruje se 5 prvků od indexu 3 ve zdrojovém
poli na cílové prvky od indexu 0):
double src[] = new double[10];
double dest[] = new double[5];
... // zde se přiřazují prvky
System.arraycopy(src, 3, dest, 0, 5);
Prvky primitivních typů se nesmí typově lišit. U referenčních typů je
povolena jen taková odlišnost, kdy lze cílovému prvku ten zdrojový přiřadit
(konkrétní typ se přitom může lišit). Porušení tohoto pravidla má za
následek vyhození výjimky ArrayStoreException . V níže uvedeném
příkladu je ukázka kopírování prvků referenčního typu v rámci téhož pole
(ve čtyřprvkovém poli se první dva prvky zkopírují na zbývající místa):
Thread ta[] = new Thread[4];
ta[0] = new Thread();
ta[1] = new Thread();
System.arraycopy(ta, 0, ta, 2, 2);
Používání arraycopy() namísto klasického cyklu s postupným přiřazováním
je (kromě usnadnění práce) výhodné také z hlediska rychlosti. Metoda
má totiž obvykle nativní implementaci, takže je rychlejší než kód
přímo v Javě.
Mechanismy poskytované třídou Arrays
S pouhým kopírováním polí se určitě nespokojíme, v praxi bývá potřeba
mnohem více operací. Právě pro tyto účely je určena třída
java.util.Arrays ,
poskytující množství statických metod pro práci s poli. Pro pole primitivních
typů je chování těchto metod předem dáno, u polí referenčních typů velice
záleží na vlastnostech a chování prvků. Tak se do toho pusťme...
Převod na řetězec
Toto není metoda příliš typická pro pole (také byla přidána až ve verzi 1.5),
uvádím ji však jako první, protože se hodí pro ladění a testování programů.
Její smysl je podobný jako u stejnojmenné metody třídy Object .
Funguje tak, že vytvoří řetězec, kde jsou v hranatých závorkách textové hodnoty
jednotlivých prvků. Zde jsou dva příklady:
int ia[] = new int[3];
... // zde se přiřazují prvky
System.out.println(Arrays.toString(ia));
Object oa[] = new Object[10];
... // zde se přiřazují prvky
System.out.println(Arrays.toString(oa));
Pokud je některý z prvků sám polem, nepřevedou se na text jeho prvky, nýbrž
se mu zavolá metoda toString() z třídy Object .
Plnění polí
Často potřebujeme naplnit pole nebo jeho část nějakou konkrétní hodnotou.
K tomu slouží metoda fill() , které na jediné zavolání pole takto
naplní. Máme dvě varianty této metody - jedna naplní celé pole, u druhé
určujeme počáteční a koncový index v poli (plní se počínaje počátečním
indexem až ke koncovému, ten už není naplněn). Nejlépe vše ukáže příklad
(první plní najednou celé pole, druhý postupně dvě části pole).
int ia[] = new int[100];
Arrays.fill(la, 0);
String sa[] = new String[5];
Arrays.fill(sa, 0, 2, "text1");
Arrays.fill(sa, 2, 5, "text2");
Netřeba snad připomínat, že při plnění pole prvků referenčního typu
se odkazuje ve všech prvcích na tentýž objekt.
Porovnávání polí
Máme dvě pole a potřebujeme zjistit, zda jsou shodná. To dokáže metoda
equals() , porovnávající dvě pole z hlediska počtu prvků a
jejich hodnot.
Dvě pole jsou shodná právě tehdy, když mají stejný počet prvků a
odpovídající prvky mají stejnou hodnotu; shodné jsou i dvě prázdné
(null ) reference na pole. Porovnávat lze pole prvků stejného
primitivního typu (pak se porovnávají hodnoty prvků), nebo pole
prvků referenčního typu (v tom případě jsou prvky shodné tehdy,
prohlásí-li je za shodné metoda equals() dané třídy
nebo jsou obě reference prázdné).
byte ba1[] = new byte[10];
byte ba2[] = new byte[8];
boolean b = Arrays.equals(ba1, ba2); // vrátí false - různá délka
int ia1[] = new int[5];
int ia2[] = new int[5];
Arrays.fill(ia1, 0);
Arrays.fill(ia2, 0);
boolean b = Arrays.equals(ia1, ia2); // vrátí true - shodná pole
ia2[3] = 5;
b = Arrays.equals(ia1, ia2); // vrátí false - různé hodnoty 1 prvku
Seřazení pole
Řazení prvků pole patří mezi složitější úlohy, proto je dobře, že
je k dispozici mechanismus, který to za nás vykoná. Příslušná
statická metoda se jmenuje sort() a opět může pracovat jak na celém
poli, tak na jeho části. Řadit můžeme pole primitivních prvků i
(s určitým omezením - viz dále) prvků referencí na objekty.
Prvky primitivních typů jsou řazeny optimalizovaným algoritmem
quicksort, řadícím v čase n*log(n).
long la[] = new long[1000];
... // zde se přiřazují prvky
Arrays.sort(la);
Prvky referenčních typů můžeme řadit pouze tehdy, implementuje-li
jejich třída rozhraní
java.lang.Comparable
(ještě o něm bude řeč někdy
později) a jsou navíc vzájemně porovnatelné (jejich metoda
compareTo()
musí akceptovat typ, s nímž se prvek srovnává). Na to je třeba dát
pozor a skutečně srovávat jen to, co srovnávat lze. Pro řazení
objektů se používá algoritmus mergesort, řazení je stabilní
(předem seřazené posloupnosti již nejsou měněny).
Object oa[] = new Object[3];
oa[0] = "abc";
oa[1] = "123";
oa[2] = "%%%%%";
Arrays.sort(oa); // toto lze
oa[1] = new Double(1);
Arrays.sort(oa); // nelze, způsobí výjimku ClassCastException
Vyhledávání v poli
Poslední z věcí, na kterou se dnes podíváme, je vyhledávání prvku
v poli. To je zde implementováno jako hledání binárním dělením
- proto je nutné, aby pole bylo předem seřazeno metodou sort() .
Pokud se neseřadí, není chování algoritmu definováno.
Metoda binarySearch() vrací hledaného index prvku, nebo
zápornou hodnotu v případě nenalezení. Pro referenční typy platí stejná
pravidla jako u metody sort() - protože tuto metodu musíme
stejně předtím zavolat, není již co řešit.
float fa[] = new float[200];
... // zde se přiřazují prvky
Arrays.sort(oa); // seřazení pole
int i = Arrays.binarySearch(0.4); // vrátí index hledaného prvku
Pohodlnější práce s hromadnými daty
Pole jsou jednoduchou formou uchovávání většího množství dat. Na jejich
omezení ale narazíme již v okamžiku, kdy potřebujeme měnit počet prvků
nebo dělat nějaké složitější operace. Proto existují tzv.
kontejnery
(o nichž bude řeč příště), což jsou objekty, ve kterých máme uložena
svá data a s jejichž pomocí můžeme provádět různé operace.
Verze pro tisk
|
Příspívat do diskuze mohou pouze registrovaní uživatelé.
|
|

Vyhledávání software

Vyhledávání článků
28.11.2018 23:56 /František Kučera Prosincový sraz spolku OpenAlt se koná ve středu 5.12.2018 od 16:00 na adrese Zikova 1903/4, Praha 6. Tentokrát navštívíme organizaci CESNET. Na programu jsou dvě přednášky: Distribuované úložiště Ceph (Michal Strnad) a Plně šifrovaný disk na moderním systému (Ondřej Caletka). Následně se přesuneme do některé z nedalekých restaurací, kde budeme pokračovat v diskusi.
Komentářů: 1
12.11.2018 21:28 /Redakce Linuxsoft.cz 22. listopadu 2018 se koná v Praze na Karlově náměstí již pátý ročník konference s tématem Datová centra pro business, která nabídne odpovědi na aktuální a často řešené otázky: Jaké jsou aktuální trendy v oblasti datových center a jak je optimálně využít pro vlastní prospěch? Jak si zajistit odpovídající služby datových center? Podle jakých kritérií vybírat dodavatele služeb? Jak volit vhodné součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně datové centrum spravovat? Jak co nejlépe eliminovat možná rizika? apod. Příznivci LinuxSoftu mohou při registraci uplatnit kód LIN350, který jim přinese zvýhodněné vstupné s 50% slevou.
Přidat komentář
6.11.2018 2:04 /František Kučera Říjnový pražský sraz spolku OpenAlt se koná v listopadu – již tento čtvrtek – 8. 11. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma umění a technologie, IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
4.10.2018 21:30 /Ondřej Čečák LinuxDays 2018 již tento víkend, registrace je otevřená.
Přidat komentář
18.9.2018 23:30 /František Kučera Zářijový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 20. 9. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
9.9.2018 14:15 /Redakce Linuxsoft.cz 20.9.2018 proběhne v pražském Kongresovém centru Vavruška konference Mobilní řešení pro business.
Návštěvníci si vyslechnou mimo jiné přednášky na témata: Nejdůležitější aktuální trendy v oblasti mobilních technologií, správa a zabezpečení mobilních zařízení ve firmách, jak mobilně přistupovat k informačnímu systému firmy, kdy se vyplatí používat odolná mobilní zařízení nebo jak zabezpečit mobilní komunikaci.
Přidat komentář
12.8.2018 16:58 /František Kučera Srpnový pražský sraz spolku OpenAlt se koná ve čtvrtek – 16. 8. 2018 od 19:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát jsou tématem srazu databáze prezentaci svého projektu si pro nás připravil Standa Dzik. Dále bude prostor, abychom probrali nápady na využití IoT a sítě The Things Network, případně další témata.
Přidat komentář
16.7.2018 1:05 /František Kučera Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.
Přidat komentář
Více ...
Přidat zprávičku
 Poslední diskuze
31.7.2023 14:13 /
Linda Graham iPhone Services
30.11.2022 9:32 /
Kyle McDermott Hosting download unavailable
13.12.2018 10:57 /
Jan Mareš Re: zavináč
2.12.2018 23:56 /
František Kučera Sraz
5.10.2018 17:12 /
Jakub Kuljovsky Re: Jaký kurz a software by jste doporučili pro začínajcího kodéra?
Více ...
|