Programovßnφ v jazyce Java

Kurz programovßnφ v Jav∞ - 10. dφl

 ┌vodem  |  Kurz programovßnφ v Jav∞  |  Kurz programovßnφ v Jav∞ pro mobilnφ telefony  |  Soubory ke sta₧enφ  |  Otßzky a odpov∞di

 

┌vod

V minulΘm dφle jsme probφrali pole, ale ne°ekli jsme si nic o jejich kopφrovßnφ, dneÜnφm dφle to napravφme.


Kopφrovßnφ polφ

Pokud chceme jedno pole zkopφrovat do jinΘho, nelze pou₧φt operßtor p°i°azenφ, proto₧e by se nezkopφrovaly jednotlivΘ prvky, ale pouze odkaz na pole. To znamenß, ₧e by byly dva odkazy na stejnΘ pole, m∞nit prvky bychom mohli ob∞ma odkazy a zßrove≥ pokud bychom pole zm∞nili p°es jeden odkaz, druh² odkaz by odkazoval na to samΘ pole, to zm∞n∞nΘ p°es prvnφ odkaz.

Nßsledujφcφ ukßzka tento p°φpad demonstruje




Kopφrovßnφ odkazu na pole
...

int[] a = {10, 15, 20, 25};
int[] b;

b = a;

a[1] = 50;

System.out.println(b[1]);  // vypise 50

...
	  



Na prvnφch dvou °ßdcφch jsme deklarovali dv∞ pole, pole a typu int a pole b takΘ typu int. Dßle jsme pole a inicializovali 4 hodnotami. Potom jsme prom∞nnΘ b p°i°adili odkaz na pole. Te∩ ob∞ prom∞nnΘ odkazujφ na stejnΘ pole, co₧ dokazuje nßsledujφcφ °adek na kterΘm se 2. hodnot∞ pole a p°i°adφ hodnota 50 a nakonec nechßme vypsat druhou hodnotu pole b, kterß je takΘ 50. Toto chovßnφ je sice logickΘ, ale nemusφ b²t na prvnφ pohled z°ejmΘ.

Jak tedy zkopφrovat jednotlivΘ prvky pole?



Kopφrovßnφ pole
...

int[] a = {10, 15, 20, 25};
int[] b;

// b = a;
b = new int[a.length];

for (int i = 0; i < a.length; i ++) {

	b[i] = a[i];

}

a[1] = 50;

System.out.println(b[1]);

...
	  


Pomocφ cyklu for se zkopφrujφ jednotlivΘ prvky jednoho pole do pole druhΘho. Nemusφ se pou₧φvat jen cyklus for, jde to i pomocφ while cyklu.

DalÜφ zajφmavostφ je kopφrovßnφ vφcerozm∞rnΘho pole, v naÜem p°φkladu to bude pole dvourozm∞rnΘ, ale nem∞l by b²t problΘm podle tohoto p°φkladu odvodit i pole o vφce rozm∞rech ne₧ jsou dva. Te∩ ji₧ slφben² p°φklad:



Kopφrovßnφ dvourozm∞rnΘho pole
...

int[][] a = { {1, 2, 3},
  	  {10, 15, 20},
	  {50, 60, 70},
	};
int[][] b;
	
b = new int[a.length][a[0].length];

for (int i = 0; i < a.length; i ++) {
	for (int j = 0; j < a[i].length; j ++) {
	
		b[i][j] = a[i][j];
		
	}
}

...
	  


Myslφm, ₧e p°φklad nepot°ebuje dalÜφho vysv∞tlovßnφ. Pokud vßm na tom nenφ n∞co jasnΘ, zkuste si pole sami naplnit Φφsly a nechte si je v ka₧dΘ smyΦce vypisovat na konzoli pomocφ metody System.out.println().

Kopφrovßnφ polφ pomocφ metody System.arraycopy()

Pou₧itφ metody arraycopy() je jednoduchΘ a vÜechnu prßci ud∞lß za vßs. Nßsledujφc p°φklad ukazuje jak metodu arraycopy() pou₧φt.



Kopφrovßnφ pole pomocφ metody System.arraycopy()
...

int[] a = {10, 15, 20, 25};
int[] b;

b = new int[a.length];

System.arraycopy(a, 0, b, 0, a.length);

System.out.println(b[2]); // b[2] je 20

...
	  


Prvnφm argumentem metody arraycopy() je prom∞nnß obsahujφcφ pole, kterΘ chceme kopφrovat. Druh²m argumentem je Φφslo typu int a urΦuje od kterΘho prvku pole ho chceme kopφrovat. DalÜφm t°etφm argumentem je zase prom∞nnß typu pole, kterß odkazuje na pole, kterΘ chceme naplnit prvky z prvnφho pole. P°eposlednφm argumentem je znovu Φφslo typu int, kterΘ urΦuje prvnφ prvek od kterΘho se zaΦnou hodnoty z prvnφho pole kopφrovat. Poslednφm argumentem je op∞t Φφslo typu int, kter²m urΦφme poΦet prvk∙ ke zkopφrovßnφ.

V dalÜφm p°φkladu m∙₧ete vid∞t vyu₧itφ argument∙ s nenulov²mi hodnotami, kterΘ znamenajφ, ₧e se prvnφ pole kopφruje od zaΦßtku, do druhΘho kterΘ, se napl≥uje od zaΦßtku.



Kopφrovßnφ pole pomocφ metody arraycopy()
...

int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] b = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110};

System.arraycopy(a, 4, b, 6, 5);

for (int i = 0; i < b.length; i ++) {

	System.out.println(b[i]);
	
}

...
	  


Zatφm jsme si ukßzali pou₧itφ metody arraycopy() pouze p°i kopφrovßnφ jednorozm∞rnΘho pole. Podφvejte se na nßsledujφcφ p°φklad.



Kopφrovßnφ odkaz∙ pole pomocφ arraycopy()
...

int[][] a = { {1, 2, 3},
  	  {10, 15, 20},
	  {50, 60, 70},
	};
int[][] b;
	

b = new int[a.length][a[0].length];

System.arraycopy(a, 0, b, 0, a.length);

...
	  


P°i takovΘm pou₧itφ metody arraycopy() na vφcerozm∞rnß pole vznikne stejnß situace jako kdy₧ pou₧ijeme ke zkopφrovßnφ jednorozm∞rnΘ pole operßtor p°i°azenφ =. Pouze se zkopφrujφ odkazy na jednotlivΘ °ßdky dvourozm∞rnΘho pole. Proto, pokud chceme pou₧φt metodu arraycopy() na vφce rozm∞rnß pole musφme pou₧φt n∞jak² cyklus (nebo cykly), stejn∞ jako ukazuje nßsledujφcφ p°φklad.



Kopφrovßnφ dvourozm∞rnΘho pole pomocφ arraycopy()
...

int[][] a = { {1, 2, 3},
  	  {10, 15, 20},
	  {50, 60, 70},
	};
int[][] b;

b = new int[a.length][a[0].length];

for (int i = 0; i < a.length; i ++) {
	
	System.arraycopy(a[i], 0, b[i], 0, a[i].length);
	
}

...
	  


Na zßv∞r dφlu jsem p°ipravil p°φklad, kter² ukazuje kopφrovßnφ trojrozm∞rnΘho pole :-).

Kopφrovßnφ trojrozm∞rnΘho pole
...

int[][][] a = { { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} },
  	  { {10, 11, 12}, {13, 14, 15}, {16, 17, 18} },
	};
int[][][] b;

b = new int[a.length][a[0].length][a[0][0].length];

for (int i = 0; i < a.length; i ++) {
	for (int j = 0; j < a.length; j ++) {
		for (int k =0; k < a.length; k ++) {
		
			b[i][j][k] = a[i][j][k];
		
		}
	}
}

...
	  


Zßv∞r

Dnes jsme probrali kopφrovßnφ polφ, mo₧nß to nenφ nejpodstatn∞jÜφ v∞c p°i programovßnφ, ale urΦit∞ se bude hodit a mnohokrßt ji vyu₧ijete. Obsah p°φÜtφho dφlu bude p°ekvapenφm :-). Pokud by n∞kdo cht∞l probrat n∞jakΘ tΘma, kterΘ se neprobφralo a pravd∞podobn∞ probφrat nebude, napiÜte mi a jß ho za°adφm.



Alen Dvo°ßk