====== Dvojrozměrná pole ====== Dvojrozměrná pole v Javě jsou pole obsahující jednorozměrná pole. int [] [] a = { { 1, 2, 3}, { 10, 20 } }; * a.length je počet prvků nižší dimenze (říkejme jim řádky) (v našem případě 2) * **a[0]** a **a[1]** jsou jednorozměrná pole (řádky) * **a[0].length** je počet prvků v řádce **a[0]** (tj. 3) * všechny řádky nemusí výt stejně dlouhé * některé řádky mohou mít nula prvků * místo některých řádek může být **null** (např. všechny řádky pole **c** na následujícím obrázku) (u takových řádek nelze zjišťovat ani počet prvků.) === Dynamicky vytvořené pole inicializované nulami === * V deklaraci typu uvedeme jen prázdné závorky naznačující počet rozměrů * Pole vytvoříme výrazem **new int [ počet řádek ] [ počet sloupců ]**, počty řádek a sloupců mohou být zadány libovolnými výrazy int [] [] b = new int [2] [3]; === Zadáme počet prvků pro nejvyšší dimenzi, místo ostatních necháme prázdné závorky === int [] [] c = new int [3] [ ]; * Vznikne dvojrozměrné pole, které má místo všech řádek null (viz. následující obrázek) * Lze použít při vytváření např. trojúhelníkového pole c[0] = new int [] { 1, 2, 3 }; c[1] = new int [] { 10, 20 }; c[2] = new int [] { 100 }; nebo c[0] = new int [] { }; // c[0] má nula prvků c[1] = new int [] { 10 }; // c[1] má jeden prvek c[2] = new int [] { 100, 200 }; === Při větším počtu dimenzí můžeme zadat několik nejvyšších hodnot === Můžeme např. vytvořit pole 3 x 2, obsahující nulové ukazatele na dvojrozměrná pole int [][][][] t = new int [3][2][][]; System.out.println (t.length); // vytiskne 3 System.out.println (t[0].length); // 2 System.out.println (t[0] == null ? "null" : "array"); // array System.out.println (t[0][0] == null ? "null" : "array"); // null === Obrázek === * pole **d** má nula řádek * proměnná **e** obsahuje **null** * proměnná typu pole je vždy odkaz (ukazetel) * pokud je tento ukazatel **null**, __nelze__ zjišťovat pomocí **proměnná.length** délku * pokud není null, ukazatel vede na datovou strukturu obsahující počet prvků a jednotlivé prvky * jednotlivé prvky primitivních typů (boolean, char, short, int, long, float, double) jsou uloženy přímo v poli * pokud jsou prvky objekty nebo jiná pole jsou zde uloženy ukazatele, které opět mohou být null int [] [] a = { { 1, 2, 3}, { 10, 20 } }; int [] [] b = new int [2] [3]; int [] [] c = new int [3] [ ]; int [] [] d = new int [0] [0]; int [] [] e = null; int [] [] p = a; * Proměnné typu pole (odkazy na pole) jsou nakresleny jako //červené// obdélníky. * //Žluté// obdélníky obsahují počet prvků v poli * Počet ukazatelů naznačují //zelené// čárky. * Celočíselné hodnoty jsou uvnitř //světle modrých// obdélníků * //Tmavě modré// jsou prvky dvojrozměrných polí představující odkaz (ukazetel) na jedorozměrné pole {{pole2d.png}} ===== Zobrazení dvojrozměrných polí ===== * Ve funkci main zavoláme funkci **demo ("jméno pole", proměnná typu dvojrozměrné pole celých čísel)** * Funkce demo vytvoří instanci typu **Display2D**, okno zobrazí (**setVisible**) a umístí na obrazovce (**setLocation**) * V kontruktoru třídy //Display2D// je zavolána funkce **put** * Tato funkce nejprve zkontroluje zda odkaz na pole (parametr **a**) není null * Pokud parametr není null, lze zjistit počet řádek **a.length** * Pro jednotlivé řádky přidáme do okna objekt typu **DisplayPanel** package experiment; import java.awt.*; import org.netbeans.lib.awtextra.AbsoluteConstraints; public class Display2D extends javax.swing.JFrame { public Display2D () { initComponents(); getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.Y_AXIS)); } public Display2D (String name, int [ ] [ ] a) { this (); put (name, a); } private void initComponents() { /* ... */ } public void put (String name, int [] [] a) { if (a == null) { setTitle (name + " == null"); } else { int n = a.length; setTitle (name+ ", " + name + ".length == " + n); Container target = getContentPane(); for (int i = 0; i < n; i++) { DisplayPanel d = new DisplayPanel (name + "[" + i + "]", a[i]); target.add (d); } pack (); } } private static int x = 10; private static int y = 10; public static void demo (String name, int [] [] a ) { Display2D w = new Display2D (name, a); w.setVisible (true); w.setLocation (x, y); x = x + 40; y = y + 40; } public static void main(String args[]) { int [] [] a = { { 1, 2, 3}, { 10, 20 } }; int [] [] b = new int [5] [5]; int [] [] c = new int [3] [ ]; int [] [] d = new int [0] [0]; int [] [] e = null; demo ("a", a); demo ("b", b); demo ("c", c); demo ("d", d); demo ("e", e); int [] [] t = new int [5] [ ]; int base = 1; for (int i = 0; i < t.length; i++) { t[i] = new int [t.length - i]; for (int k = 0; k < t[i].length; k++) t[i][k] = (k+1) * base; base *= 10; } demo ("t", t); } } [[https://gitlab.fjfi.cvut.cz/culikzde/java-priklady/-/blob/master/Array/src/experiment/Display2D.java|Display2D]] * **DisplayPanel** je podobný třídě **Display** z kapitoly o jednorozměrných polech * Funkce **put** má za parametry název pole a odkaz na jednorozměrné pole celých čísel * Funkce nejprve zkontroluje zda odkaz na jednorozměrné pole není //null// * Pokud odkaz není null, zjistí délku pole a alokuje dvě nová pole * Jednorozměrné pole **title** obsahující **n** nadpisů (typu String) * Dvojrozměrné pole **data**, které má jednu řádku a **n** sloupců int n = a.length; String [] title = new String [n]; String [] [] data = new String [1] [n]; Pole naplníme hodnotami for (int i = 0; i < n; i++) { title [i] = name + "[" + i + "]" ; data [0][i] = "" + a[i]; // convert to string } Vytvoříme **model**, který bude tabulce typu **JTable** dodávat data na základě našich dvou polí. \\ A //model// předáme tabulce. DefaultTableModel model = new DefaultTableModel (data, title); jTable1.setModel (model); Téměř celá třída DisplayPanel public class DisplayPanel extends javax.swing.JPanel { public DisplayPanel () { initComponents(); } public DisplayPanel (String name, int [] a) { initComponents(); put (name, a); } public void put (String name, int a []) { if (a == null) { jLabel1.setText ("null"); jLabel1.setForeground (new Color (255, 0, 0)); jLabel1.setFont(new java.awt.Font("Dialog", 0, 36)); jTextField1.setText ("null"); jTextField1.setForeground (new Color (255, 0, 0)); // remove (jTable1); // getContentPane().remove (jS) jTextField1.setVisible (false); jScrollPane1.setVisible (false); } else { int n = a.length; jLabel1.setText (name + ".length"); jTextField1.setText ("" + n);// convert to string String [] title = new String [n]; String [] [] data = new String [1] [n]; for (int i = 0; i < n; i++) { title [i] = name + "[" + i + "]" ; data [0][i] = "" + a[i]; // convert to string } DefaultTableModel model = new DefaultTableModel (data, title); jTable1.setModel (model); TableColumnModel columnModel = jTable1.getColumnModel(); for (int i = 0; i < n; i++) columnModel.getColumn(i).setMaxWidth (80); if (n == 0) jScrollPane1.setVisible (false); } } } [[https://gitlab.fjfi.cvut.cz/culikzde/java-priklady/-/blob/master/Array/src/experiment/DisplayPanel.java|DisplayPanel]] ===== Výstup ===== int [] [] a = { { 1, 2, 3}, { 10, 20 } }; int [] [] b = new int [5] [5]; int [] [] c = new int [3] [ ]; {{array_2d1.png}} ===== Trojúhelníkové pole, pole s nula prvky, nulový ukazatel na pole ===== int [] [] d = new int [0] [0]; int [] [] e = null; int [] [] t = new int [5] [ ]; int base = 1; for (int i = 0; i < t.length; i++) { t[i] = new int [t.length - i]; for (int k = 0; k < t[i].length; k++) { t[i][k] = (k+1) * base; } base *= 10; } demo ("t", t); {{array_2d2.png}} [[https://gitlab.fjfi.cvut.cz/culikzde/java-priklady/-/blob/master/Array/src/experiment/Display2D.java|gitlab]] [[http://kmlinux.fjfi.cvut.cz/~culikzde/sos/Array2020.zip|zip]]