Objektorientiert programmieren mit Java (1)

1 Java Einstieg

1.1 Datentypen in Java

1.1.1 Ganzzahlen

1.1.2 Gleitpunkt

1.1.3 Boolean

Hintergrund:
in manchen Anwendungssituationen werden "Schalter"-Funktionalitäten benötigt;
diese können über "Zahlenvariablen" mit 2 unterschiedlichen erlaubten Werten umgesetzt werden, ODER über Variablen vom Typ boolean , die nur 2 unterschiedliche Werte erlauben
außerdem könnte in einer solchen Variablen auch der Ergebniswert eines beliebigen logischen Ausdrucks gespeichert werden
Syntax für Definition:
boolean Bezeichner; //definiert 1 Variable OHNE Initialisierung
boolean Bez1, Bez2; //definiert 2 Variablen OHNE Initialisierung
boolean[] Bez = new boolean[1000]; //definiert eine Referenzvariable und initialisiert 
                                   //diese mit der Adresse eines 1000-elementigen Arrays,
                                   //wobei alle Elemente mit false initialisiert sind
					
Arbeiten mit boolean-Variablen
Initialisieren bzw. Wertzuweisung der 2 möglichen Konstanten true oder false
z.B.:
boolean b1 = true, b2 = false, b3;
b3 = true;
Wertzuweisung des Ergebnisses eines logischen Ausdruckes
z.B.:
...
b3 = a > b && c < 0 || d !=e
Auswerten von boolean-Variablen:
d.h. Ermitteln des Wertes einer boolean-Variablen
  1. Prüfen, ob Variable den Wert true enthält:
    if(b==true)besser: if(b)
  2. Prüfen, ob die Variable den Wert false enthält:
    if(b==false)besser: if(!b)
Typisches 1. Einsatzbeispiel:
  1. "Schalter"-Funktionalität mit int-Variable implementiert:
    int g = 0, i = 0;
    while(i < z.length && g == 0)
        if(z[i] == such)
            g = 1;
        else
            i++;
        if(g == 1)
            ...
  2. "Schalter"-Funktionalität (1:1) über boolean-Variable implementiert:
    								boolean gefunden = false;
    int i = 0;
    while(i < z.length && gefunden == false)
        if(z[i] == such)
            gefunden == true;
        else
            i++;
        if(gefunden == true)
            ...
    
    BESSER:
    
    boolean gefunden = false;
    int i = 0;
    while(i < z.length && gefunden)
        if(z[i] == such)
            gefunden == true;
        else
            i++;
        if(gefunden)
            ...
                                    

1.2 Umsetzung des Datenmodells
(im Rahmen der Entwicklung der Ablauflogik in Struktogrammen)

Hintergrund:
wie muss das skizzierte Datenmodell im zu erstellenden Java-Quelltext berücksichtigt werden?
Umsetzung:
durch Definitions-Anweisungen (vor den ausführbaren Anweisungen)
Syntax von Definitionsnaweisungen:
  1. Datentyp Bezeichner; z.B. int zahl;
    Wirkung:
    Reservierung von 4 Byte Speicherplatz, der über zahl ansprechbar ist; Speicherinhalt ist UNDEFINIERT!
  2. Datentyp Bez1,Bez2,Bez3; z.B. double ein,maxi,mini;
    Wirkung:
    Definieren nicht nur einer, sondern mehrerer Variablen DESSELBEN Datentyps
  3. Datentyp Bezeichner = Wert; z.B. int summe = 0;
    Wirkung:
    der durch die Definition reservierte Speicherplatz wird SOFORT "initialisiert", d.h. mit einem kontrollierten Ausgangswert versorgt
    Hinweis:
    bei "Mehrfachdefinitionen" sind nur DIE Variablen initialisiert, für die ein Wert zugeordnet wird!
    z.B. double q=1.1,b,c=3.3; Nur a und c sind initialisiert, n NICHT!
    Wert ist typischerweise eine Konstante
Regeln für Bezeichner
  • case-sensitiv! (Es wird auf Groß- und Kleinschreibung geachtet)
  • zusammengesetzt aus Buchstaben (A...Z, a...z)
  • Ziffernzeichen (0-9)
  • Unterstrich und Dollarzeichen
  • Das erste Zeichen darf KEIN Ziffernzeichen sein!

Alle Definitionsanweisungen SOLLTEN VOR der ersten ausführbaren Anweisung im Quelltext angegeben sein!

1.3 Umsetzung der Struktogramme in Java-Quelltexte

Allgemein:
allgemein
daraus resultierender Grundaufbau einer Java-Anweisung:
public class Name
{
    public static void main(String[]args)
    {
        Definitionsanweisungen ... ausführbare Anweisungen ...
    }							
}
					

1.4 Umsetzung der ausführbaren Anweisung (aus den Struktogrammen)

(1) Ausgabe-Anweisung:
Ausgabeanweisung System.out.println("Meldung...");
println = automatisches "Ausgeben" eines Zeilenumbruches am Ende
Ausgabeanweisung2 System.out.print("Eine Zahl bitte: ");
print = ohne Zeilenumbruch am Ende
Ausgabeanweisung System.out.println("Ergebnis: " + summe);
(2) Eingabe-Anweisung:
Eingabeanweisung 1
Ergänzende Definitonsanweisung:
Scanner ein = new Scanner(System.in);
zwischen "package ..." und "public class ..." einfügen
"Eigentliche Eingabe:" Variablenname = ein.nextDatentyp();
konkret:
int zahl; → zahl = ein.nextInt();
double wert; → wert = ein.nextDouble();
(3) Arthmetische Ausdrücke:
wie im Struktogramm (Ausnahme: "Potenzierungs-Operator" nicht verwendbar")
JEDE Anweisung aus dem Struktogramm, muss mit einem Strichpunkt ; abgeschlossen werden!
(4) Logische Ausdrücke:
einfache Vergleiche: wie im Struktogramm
UND-Verknüpfung: statt UND: &&
ODER-Verknüpfung: statt ODER: ||
logische Negation: statt: NICHT: !
z.B.:
a > 5 UND b >= c ODER NICHT (d < 0 UND e < 0)
a > 5 && b >= c || !(d < 0 && e < 0)
(5) Alternative (bzw. bedingte Verarbeitung)
(a) Alternative Beispiel 1
if (Bed)
    eine_Anw1;
else
    eine_Anw2;
(b) Alternative Beispiel 2
if (Bed)
{
    AnwL1;
    AnwL2;
    AnwL3;
}
else
{
    AnwR1;
    AnwR2;
(c) Alternative Beispiel 3
if (Bed)
    Anw;
Besser:
if (Bed)
    ;
else
    Anw;
Alternative Beispiel 4
if (Bed)
    ;
else
    Anw;
    
Besser:

if (!(Bed))
    Anw;
(6) Schleifen
(a) Kopfgesteuerte
Schleife Kopf 1
while(Laufbedingung)
eineAnw;
Schleife Kopf 2
while(Laufbedingung)
{
    Anw1;
    Anw2;
}
(b) Fußgesteuerte
Schleife Fuss 1
do
    eineAnw;
while(Laufbedingung)
Schleife Fuss 2
do
{
    Anw1;
    Anw2;
}
while(Laufbedingung)
Laufbedingung entsteht durch Negation der Abbruchbedingung!
(c) Abbruch-Schleifen
Schleife Abbruch
while(true)
{
    Anw1;
    Anw2;
}
if (Abbruchbedingung) break;
    Anw3;
}
(7) Erweiterte Möglichkeiten für arithmetische Ausdrücke in Kombination mit Wertzuweisung
  1. Werte in einer Summe aufaddieren bzw. in ein "Produkt" reinmultiplizieren
    Beispiel:
    int summe, zahl;
    ...
    summe = summe + zahl;
    kürzer: summe += zahl;
    allgemein
    a = a + b; a += b;
    a = a - b; a -= b;
    a = a * b; a *= b;
    a = a / b; a /= b;
    a = a % b; a %= b;
  2. Wert in einer Variablen um 1 erhöhen/vermindern
    Beispiel
    int i = d;
    allgemein:
    i = i + 1; i += 1; i ++; ++i; "Inkrement"-Operator
    i = i - 1; i -= 1; i --; --i; "Dekrement"-Operator
(8) Umsetzung SPEZIELLER kopfgesteuerter Schleifen
besondere Merkmale solcher Schleifen:
  1. es gibt eine "Zähler"-Variable (z.B. um die Anzahl der Schleifendurchläufe zu steuern bzw. die Indexwerte für Array-Zugriffe)
  2. Unmittelbar VOR der Schleife (d.h. VOR Bewertung der Laufbedingung) wird diese "Zähler"-Variable vorbelegt
  3. in der Laufbedingung wird diese "Zähler"-Variable ausgewertet
  4. ALS LETZTE Anweisung im (gesamten) Schleifenkörper wird die "Zähler"-Variable verändert
Spezielle Kopfschleife in Java
summe = 0;
zahl = 5; 
while (zahl <= obergrenze)
{
    summe += zahl;
    zahl += 5; 
}
Eleganter
summe = 0;
for (zahl = 5; zahl <= obergrenze; zahl += 5)
    summe += zahl;
(9) Kommentare in Java-Quelltexten
erlauben es Entwicklern ergänzende Hinweise in den Quelltexten anzugeben; Kommentare werden vor dem Übersetzen durch den Compiler "entfernt"
  1. 1-zeilige Kommentare: eingeleitet mit //
    wird AUTOMATISCH beendet am Zeilenende
  2. mehrzeilige Kommentare: eingeleitet mit /* beendet mit */

Hinweis: mehrzeilige Kommentare dürfen NICHT ineinander verschachtelt werden!

(10) Ausgewählte "Steuerzeichen" für Ausgaben
können NICHT "normal" über Tastatur im Quelltext eingetippt werden!
innerhalb von Zeichenketten-Konstanten, müssen hierfür besondere Zeichenkombinationen angegeben werden;
das 1. Zeichen hierfür ist ein \ ;
unmittelbar danach kann folgen:
  1. \n für Zeilenumbruch ("Newline")
  2. \t für Tabulatorsprung
  3. \" für Gänsefüßchen
  4. \\ für einen Backslash
(11) Möglichkeiten der Schreibweise konstanter Zahlenwerte
  1. für ganzzahlige Werte:
    • "normal" dezimal:
      • optionales Vorzeichen, anschließend Ziffernzeichen 0 ... 9
      • Besonderheit: das erste Ziffernzeichen (von mehreren) darf keine 0 sein!
      • z.B.: -123 oder +5 oder 47359 oder 0
    • binär:
      • optionales Vorzeichen, anschließend 0B bzw. 0b, anschließend Ziffernzeichen 0 oder 1
      • z.B.: -0B101 oder +0b1001 oder 0b11001101
    • oktal:
      • optionales Vorzeichen, anschließend 0, anschließend Ziffernzeichen 0 ... 7
      • z.B.: -0123 oder + 0456 oder 077
    • hexadezimal:
      • optionales Vorzeichen, anschließend 0x bzw. 0x, anschließend Ziffernzeichen 0 ... F oder 0 ... f
      • z.B.: -0XDB oder +0xa2b oder 0X123
  2. für Gleitpunktwerte:
    • hier darf NUR der ganzzahlige Anteil (Vorkommabereich) auch in anderen Zahlensystemen als dem dezimalen angegeben werden!
    • z.B.: double d;
      d = 0XDB OK!
      d = 0XD.B Fehler!
  3. Initialisieren bzw. Wertzuweisung für ALLE "Zahlen"-Datentypen in Java
    • Ganzzahlen
      "Standard" int:
      eine (normal dezimal) angegebene Konstante ist "standardmäßig" vom Typ int
      z.B.:
      int i = 123456; //Initialisierung
      int i1;
      i1 = 2000000000;
      long:
      "echte Long-Konstanten" MÜSSEN als solche ausdrücklich gekennzeichnet werden! geschieht durch Angabe von L nach der letzten Ziffer
      z.B.:
      long L1 = 20000000000L;
      Long L2;
      L2 = 2000000000 * 10L;
      byte:
      Initialisierung/Wertzweisung einer Konstanten wie üblich...
      z.B.:
      byte b = 98; //OK
      byte b1;
      b1 = 123; //OK
      b1 = 130 //Fehler!!
      Berechnungen mit Operanden vom Typ byte finden AUTOMATISCH auf der int-Ebene statt!!!
      Deshalb ist die Zuweisung eines so gebildeten Ergebnisses an eine byte-Variable NICHT erlaubt!
      z.B.:
      b1 = b1 - b; //Fehler
      b1-=b; //OK!!!
      b++; //OK
      ++b //OK
      short:
      ähnlich byte...
    • Gleitpunktzahlen:
      "Standard" double:
      eine Konstante mit einem Dezimalpunkt ist "standardmäßig" vom Typ double
      z.B.:
      -1.1    +2.3    4.    .5
      z.B.:
      double d = 1.2;
      double d1;
      d1 = 3.5;
      d1 = 456;   //impliziter Up-Cast automatisch
      d1 = 2000L; //impliziter Up-Cast automatisch
      float:
      für Initialierung und Wertzuweisung MUSS die float-Konstante explizit als solche gekennzeichnet werden, durch Angabe von F bzw. f als letztes Zeichen der Konstanten
      z.B.:
      1.5F    -3.f
      											
      z.B.:
      float f = 3.14f
      float f1;
      f1 = .75F;
      Berechnungen mit Operanden maximal vom Typ float werden TATSÄCHLICH auf float-Ebene ausgeführt!
      z.b.:
      f = f1 * 3.F; // liefert 2.25F
      f = f1 * 2; //Umwandlung von 2 nach float
(12) Typumwandlungen in Ausdrücken
  1. "Up-Casts"
    werden AUTOMATISCH ("implizit") vorgenommen, falls unterschiedliche Datentypen in den Operanden vorliegen
    nur von kleineren/ungenauen in Richtung größere/genauere hin
    d.h. byte short int long float double
  2. "Down-Cast"
    MÜSSEN ausdrücklich ("explizit") in Auftrag gegeben werden!
    eventuell verfälschte Ergebnisse liegen in der Verantwortung der Entwickler!!!
    z.B.: Runden bzw. Abschneiden...
    double summe_betraege;
    .
    .
    .
    //irgendwie gebildeter Inhalt: 3285.53
    //gewünscht: gerundet auf ganze Zahl ...
    int summe_gerundet;
    summe_gerundet = (int)(summe_betraege + 0.5)
    allgemein: "Cast-Operator": (Datentyp)
(13) Details zu Inkrement/Dekrement-Operation
Zweck:
  • der Wert des EINZIGEN Operanden soll um 1 erhöht (Inkrement ++) bzw. um 1 vermindert (Dekrement --) werden;
  • falls es sich bei Inkrement/Dekrement um die EINZIGE Operation innerhalb einer Anweisung handelt, sind z.B. a++; und ++a; gleichwertig
Unterschiede, ob Operator VOR oder NACH seinem Operanden angegeben ist:
  1. "Präfix-Notation":
    • Operator steht VOR seinem Operanden
    • z.B.: ++a --a
    • der Wert des Ergebnisses der Operation ist DER BEREITS VERÄNDERTE Wert im Operanden
    • z.B.:
      int a = 5;
      int erg;
      erg = ++a;
      //a: 6
      //erg: 6
  2. "Postfix-Notation"
    • Operator steht NACH seinem Operanden
    • z.B.: a++ bzw. a--
    • der Wert des Ergebnisses der Operation ist DER NOCH UNVERÄNDERTE Wert im Operanden
    • z.B.:
      int b = 5;
      int erg;
      erg = b--;
      //b: 4
      //erg: 5
(14) Erweiterte Möglichkeiten "for-Kopf"
allgemein:
  • for(Vorbereitung der Schleife;Laufbedingung;Aktion am Ende des Schleifenkörpers)
    {
        reduzierter Schleifenkörper
    }
  1. im ersten Teil des "for-Kopfs" dürfen auch sog. "Schleifenlokale" Variablen definiert und initialisiert werden:
    • zum Vergleich zu bisher wird am Anfang ZUSÄTZLICH der Datentyp der Zählvariablen mit angegeben
    • z.B.:
      for(int = i; i <= 4; i++)
          ...
    • Einschränkung: so definierte Variablen sind NUR INNERHALB der Schleifenkonstruktion bekannt! (d.h. sollte der Variableninhalt nach der Schleifen noch benötigt werden, kann diese Möglichkeit NICHT eingesetzt werden!)
  2. Im ersten und dritten Teil des "for-Kopfs" dürfen auch MEHRERE "Aufträge" angegeben werden:
    • vor dem ersten Strichpunkt: mehrere Vorbelegungen, durch Komma voneinander trennen
      • z.B.: for(variable1 = wert1, variable2 = wert2;...)
    • nach dem zweiten Strichpunkt: mehrere Veränderungen, durch Komma voneinander trennen
      • z.B.: for(...;...;Veränderung Variable1, Veränderung Variable2)
(15) Ternärer Operator
der einzige Operator mit 3 Operanden!
Aufbau: Operand1 ? Operand2 : Operand3
Regeln:
  • Operand1 MUSS zwingend eine "Bedingung" sein! Diese Bedingung kann beliebig komplex sein
  • Operand2 und Operand3 können sein: Konstanten oder Variablen oder beliebig komplexe (Rechen-)Ausdrücke
  • Das Ergebnis dieser ternären Operation ist ENTWEDER der Wert von Operand2 (falls Operand1 wahr ist) ODER der Wert von Operand3 (falls Operand1 falsch ist)
Beispiel1:
if(a<b)
    c = 19;
else
    c = 21;

GLEICHWERTIG ZU

c = a < b ? 19 : 21;
Beispiel2:
if(a>9 && b < 23)
    c = d + e * 1.1 - f;
else
    c = d + e * 2.2 - f;

GLEICHWERTIG ZU

c = d + e * (a > 9 && b < 23 ? 1.1 : 2.2) - f;
Beispiel3:
if(x < 0)
    System.out.println(x + " ist negativ");
else
    System.out.println(x + " ist positiv");

GLEICHWERTIG ZU

System.out.println(x + " ist " + (x < 0 ? "negativ" : "positiv")); 

2 Priorität der Operatoren

Bezeichnung Operator Priorität
Komponentenzugriff bei Klassen . 15
Komponentenzugriff bei Feldern [ ] 15
Methodenaufruf ( ) 15
Unäre Operatoren ++, --, +, -, ~, ! 14
Explizite Typkonvertierung ( ) 13
Multiplikative Operatoren *, /, % 12
Additive Operatoren +, - 11
Schiebeoperatoren <<, >>, >>> 10
Vergleichsoperatoren <, >, <=, >= 9
Vergleichsoperatoren
(Gleichheit/Ungleichheit)
==, != 8
bitweises bzw. logisches UND & 7
bitweises exklusives Oder ^ 6
bitweises bzw. logisches Oder | 5
logisches UND && 4
logisches Oder || 3
Bedingungsoperator ?: 2
Zuweisungsoperatoren =, +=, -=, *=, /=, %= 1

3 Arbeiten mit Arrays in Java

Definieren von Arrays(zunächst 1-dimensional)
in zwei Schritten:
  1. Schritt: festlegen des einheitlichen Bezeichners für ALLE Array-Elemente:
    • im Rahmen einer Definitionsanweisung: Datentyp[] Bezeichner;
    • z.B.: int[] arr1; bewirkt: arr1:
      Array 1
    Wirkung: Vorbereitung treffen, um das Ergebnis des zweiten Schrittes mit dem ersten Schritt zu verbinden
    d.h. die hier definierte Variable kann das Ergebnis des zweiten Schrittes "aufnehmen"
  2. Schritt: Festlegen der "Größe" des Arrays, d.h. der Anzahl der Elemente:
    • new Datentyp[Anzahl_Elemente]
    • z.B.: new int[1000]
    Wirkung: Reservierung von Speicherplatz für die angegebene Anzahl von Array-Elementen ...
    ... diese Anzahl von Array-Elementen werden "in eine Hülle gesetzt" (besser; in einem Array-Objekt verpackt) ...
    ... innerhalb dieses Objekts wird AUCH mit gespeichert, wie viele Elemente im Array liegen;
Verbindungsmöglichkeiten:
  • per Initialisierung: Datentyp[] Bezeichner = new Datentyp[Anzahl_Elemente];
    • z.B.: int[] arr1 = new int[1000];
  • per Wertzuweisung:
    Datentyp[] Bezeichner; // nur Bezeichner festlegen
    ...
    Bezeichner = new Datentyp[Anzahl_Elemente];
    z.B.:
    double[] arr2;
    ...
    arr2 = new double[52];
Hinweise:
  • Anzahl_Elemente kann als Konstante oder Variable oder als Ausdruck angegeben werden; in jedem Fall MUSS es aber ein GANZZAHLIGER nicht negativer Wert sein
    z.B.:
    float[] arr3 = new float[20];
    --------
    int anzahl;
    anzahl = ein.nextInt();
    short[] arr4 = new short[anzahl];
    --------
    int a,b;
    a = ...;
    b = ...;
    long[] arr5 = new long[a+b];
  • ALLE Array-Elemente sind AUTOMATISCH mit (passender) 0 initialisiert!
  • ein LESENDER Zugriff auf die IM Array-Objekt mit gespeicherte Anzahl von Elementen ist möglich über:
    Bezeichner.length
    z.B.: arr3.length ... 20
Visualisierung Verwaltung/Speicherung von Arrays:
z.B.: int[] arr = new int[5];
Array 5
(weitere) ausführbare Anweisung zu Arrays: GENAU wie im Struktogramm!
Beispiel1:
  • Ein 9-elementiges int-Array soll mit den Werten 11, 22, 33, ..., 99 vorbelegt werden
  • Anschließend soll der Inhalt eines jeden Elements zusammen mit einer "Elementnummer" ausgegeben werden
  • package woche2;
    
    
    public class ArrBeispiel1 
    {
        public static void main(String[] args) 
        {
            int[] arr = new int[9];
            
            for(int i = 0;i < 9; ++i)
            {
                arr[i] = 11 * (i + 1);
            }
            
            for(int i = 0;i < 9; ++i)
                System.out.println("Element: " + (i+1) + " Wert: " + arr[i]);
        }
    
    }
Beispiel2:
  • Für mehrere Vertreter sollen (tägliche) Umsätze in einem float-Array "gesammelt" werden;
  • Von wievielen Vertretern tatsächlich Umsatzangaben vorliegen, muss zu Beginn der Anwendung eingegeben werden
  • anschließend soll der durchschnittliche Umsatz berechnet und ausgegeben werden.
  • abschließend ist zu ermitteln und auszugeben, wieviele Umsätze unter dem Durchschnitt lagen
  • package woche2;
    
    import java.util.Scanner;
    
    public class ArrBeispiel2 
    {
        public static void main(String[] args) 
        {
            Scanner ein = new Scanner(System.in);
            
            float[] vums;
            int vanz;
    
            System.out.print("Anzahl Vertreter: ");
            vanz = ein.nextInt();
            
            vums = new float[vanz];
            
    // Teil 1: Array über Eingaben füllen
    
            for(int i = 0; i < vums.length; i++)
            {
                System.out.print((i+1) + ". Umsatz: ");
                vums[i] = ein.nextFloat();
            }
            
    // Teil 2: Array auswerten - Durchschnitt ermitteln
            
            float gums = 0.f;
            
            for(int i = 0; i < vums.length; i++)
                gums += vums[i];
            float dums = gums/vums.length;
            System.out.println("Der Durchschnitt liegt bei: " + dums);
            
    // Teil3: Ermitteln wieviele Array-Element unter dem Durschnitt liegen
    
            int anz = 0;
            
            for(int i = 0; i < vums.length; i++)
                if(vums[i] < dums)
                    anz++;
            System.out.println("Anzahl Umsätze unter Durchschnitt: " + anz);
            
            
        }
    
    }

3.1 Alternative für das Anlegen eines Array-Objekts mit individueller Initialisierung aller Elemente

Hintergrund:
es soll dabei AUCH verhindert werden, dass die angelegten Elemente standardmäßig mit 0 initialisiert werden
Allgemein:
Datentyp[] Bezeichner = {Liste von Werten};
Wirkung
es wird ein Array-Objekt angelegt mit sovielen Elementen, wie in der Liste Elemente enthalten sind
dabei wird das 1. Array-Element mit dem 1. Wert aus der Liste, das 2. Array-Element mit dem 2. Wert aus der Liste, usw. initialisiert
Beispiel1:
byte[] tpm = {31,28,31,30,31,30,31,31,30,31,30,31}

4 Arbeiten mit 2-dimensionalen Arrays

Definition:
  1. Schritt: Definieren der Referenzvariable: Datentyp[][] Bezeichner;
    • z.B.: float[][] arr2;
  2. Schritt: Anlegen eines 2-dim. Array-Objektes: ... new Datentyp[Anzahl_Zeilen][Anzahl_Spalten];
    • z.B.: int[][] arr2D = new int[4][5]
bildliche Vorstellung:
wie üblich ...
Tatsächliche Speicherung:
am Beispiel: int[][] arr2D = new int[4][5];
Array 2D
Individuelles Initialisieren 2-dim Arrays:
Datentyp[][] Bezeichner = {{Werteliste}, {Werteliste} ...}
z.B.: int[][] arr = {{11,12,13},{21,22,23}};
Array 2D Beispiel
Zugriff auf ein bestimmtes Element "des 2-dim. Arrays":
wie gewohnt: Bezeichner[Zeilenindex][Spaltenindex]
z.B.: System.out.println(arr[1][2]); Ausgabe: 23

5 Grundlagen einer formatierten Ausgabe