====== 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]]