Abteilung Informatik, Fach Programmieren FHZ Hochschule für Technik+Architektur Luzern 13 ARRAYS 13 ARRAYS 1 Einführung Ein Array (Feld) enthält eine Anzahl von gleichartigen Komponenten (Elemente), die nicht via Namen, sondern über einen Index zugegriffen werden. Komponenten können von einem elementaren Datentyp oder können Objekte sein. Ein Array wird wie ein Objekt gehandhabt. Aber: Es besitzt nur die Superklasse Object, es besitzt eine abweichende Syntax und benutzerdefinierte Methoden sind nicht möglich. Die Anzahl der Komponenten bzw. die Länge eines Arrays wird bei der Deklaration festgelegt und kann anschliessend nicht mehr geändert werden. Die Länge eines Arrays kann aber via Zugriff auf die Instanzvariable length ermittelt werden. Die Indizierung der Komponenten ist fest vorgegeben und beginnt mit dem Index 0. Falls ein Array n Komponenten besitzt, haben diese somit Indizes von 0 bis (n-1). Zur Indizierung dienen nichtnegative Integervariablen der elementaren Datentypen byte, short und int (in der Regel int). Möglich ist auch char, wobei dann der Unicode des Zeichens verwendet wird. Gemäss dem Wertebereich von int sind Arrays bis zur Länge 231 möglich! Das Java Laufzeitsystem überprüft alle Array-Zugriffe auf Zulässigkeit. Zugriffe auf nicht initialisierte Arrays oder Zugriffe mit unzulässigen Indizes werden abgefangen und lösen eine Exception aus. Man unterscheidet ein- und mehrdimensionale Arrays. Bei einem mehrdimensionalen Array sind die Komponenten wiederum Arrays. 13 Arrays.doc, V67 © H. Diethelm Seite 1/15 FHZ Hochschule für Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren 13 ARRAYS 1.1 Beispiele für eindimensionale Arrays Vektor Messwertreihe Sammlung Array mit n Komponenten (int-Werte): 1.2 Beispiele für mehrdimensionale Arrays Spielbrett Oberflächenmodell, Körpermodell Matrix 2dimensionales Array mit m⋅n Komponenten (String-Objekte): 13 Arrays.doc, V67 © H. Diethelm Seite 2/15 Abteilung Informatik, Fach Programmieren FHZ Hochschule für Technik+Architektur Luzern 13 ARRAYS 1.3 Beispiel für eine "dreieckige" Arraystruktur (vgl. PASCAL-Dreieck) c c[2][c[2].length-1] 0 1 1 1 1 2 1 2 1 3 1 3 3 1 0 1 2 3 c[3][3] Interne Repräsentation: 13 Arrays.doc, V67 © H. Diethelm Seite 3/15 Abteilung Informatik, Fach Programmieren FHZ Hochschule für Technik+Architektur Luzern 13 ARRAYS 2 Array-Komponenten sind von einem elementaren Datentyp 2.1 Eindimensionale Arrays Deklaration: // mit 2 Anweisungen: int[] a; a = new int[5]; // mit 1 Anweisung: int[] a = new int[5]; Initialisierung: // mit a[0] = a[1] = a[2] = a[3] = a[4] = Wertzuweisungen: 0; 2; 4; 6; 8; // mit einer Schleife: for (int i=0; i<5; i++) { a[i] = i*2; } // Deklaration inklusive Initialisierung: int[] a = {0, 2, 4, 6, 8}; 13 Arrays.doc, V67 © H. Diethelm Seite 4/15 Abteilung Informatik, Fach Programmieren FHZ Hochschule für Technik+Architektur Luzern 13 ARRAYS 2.2 Mehrdimensionale Arrays Deklaration: // mit 2 Anweisungen: int[][] b; b = new int[2][3]; // mit 1 Anweisung: int[][] b = new int[2][3]; Initialisierung: // mit Wertzuweisungen: b[0][0] = 0; b[0][1] = 1; b[0][2] = 2; b[1][0] = 1; b[1][1] = 2; b[1][2] = 3; // mit zwei verschachtelten Schleifen: for (int row=0; row<2; row++) { for (int col=0; col<3; col++) { b[row][col] = row + col; } } // Deklaration inklusive Initialisierung: int[][] b = {{0, 1, 2},{1, 2, 3}}; 13 Arrays.doc, V67 © H. Diethelm Seite 5/15 FHZ Hochschule für Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren 13 ARRAYS 2.3 Speziell Arraystrukturen Deklaration in Kombination mit der Initialisierung: int n = 100; // Array mit n Array-Komponenten für int-Werte // deklarieren: int[][] pascalDreieck = new int[n][]; for (int i=0; i<n; i++) { // An der Stelle i ein Array für (i+1) // int-Werte einfügen: pascalDreieck[i] = new int[i+1]; // Komp. "links aussen" initialisieren: pascalDreieck[i][0] = 1; // Interne Werte aus obiger Zeile // berechnen: for (int j=1; j<i; j++) { pascalDreieck[i][j] = pascalDreieck[i-1][j-1] + pascalDreieck[i-1][j]; } // Komp. "rechts aussen" initialisieren: pascalDreieck[i][i] = 1; } 13 Arrays.doc, V67 © H. Diethelm Seite 6/15 Abteilung Informatik, Fach Programmieren FHZ Hochschule für Technik+Architektur Luzern 13 ARRAYS 3 Array-Komponenten sind Objekte Deklaration eines Arrays: // mit 2 Anweisungen: Balloon[] c; c = new Balloon[3]; // mit 1 Anweisung: Balloon[] c = new Balloon[3]; Instanzierung/Initialisierung der Array-Objekte: // explizit instanzieren und zuweisen; c[0] = new Balloon(0, Color.red); c[1] = new Balloon(10, Color.red); c[2] = new Balloon(20, Color.red); // mit einer Schleife: for (int i=0; i<3; i++) { c[i] = new Balloon(10*i, Color.red); } Jede Array-Komponente muss instanziert werden. Das Instanzieren des Arrays und der Komponenten läuft separat. String-Objekte werden implizit instanziert, d.h. ohne new ! 13 Arrays.doc, V67 © H. Diethelm Seite 7/15 Abteilung Informatik, Fach Programmieren FHZ Hochschule für Technik+Architektur Luzern 13 ARRAYS 4 Arrays als Parameter Array-Parameter mit beliebiger Länge: int[] table = new int[10]; for (int i=0; i<10; i++) { table[i] = i; } int total = sum(table); // => total == 45 int sum(int[] array) { int s = 0; for (int i=0; i < array.length; i++) { s = s + array[i]; } return s; } // vgl. array.length => 10 Bei formalen Array-Parametern muss die Länge des Arrays nicht spezifiziert werden. An die Methode können somit beliebig lange Arrays übergeben werden. Mit Hilfe von length kann innerhalb der Methode die aktuelle Länge des Arrays bestimmt werden. 13 Arrays.doc, V67 © H. Diethelm Seite 8/15 FHZ Hochschule für Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren 13 ARRAYS Aktuelle Array-Parameter sind Referenzen: int[][] table = new int[3][4]; fillZero(table); // => {{0,0,0,0},{0,0,0,0},{0,0,0,0}} void fillZero(int[][] array) { for (int i=0; i<array.length; i++) { for (int j=0; j<array[i].length; j++) { array[i][j] = 0; } } } // vgl. array.length => 3, array[0].length => 4 13 Arrays.doc, V67 © H. Diethelm Seite 9/15 Abteilung Informatik, Fach Programmieren FHZ Hochschule für Technik+Architektur Luzern 13 ARRAYS 5 Kopieren von Arrays Weil Arrays wie Objekte bzw. mit Hilfe von Referenzvariablen gehandhabt werden, ist Vorsicht beim Kopieren von Arrays am Platz. int[][] table1 = new int[3][4]; int[][] table2 = new int[3][4]; fillZero(table1); table2 = table1; // => ?? table1 und table2 referenzieren also ein und dasselbe Array-Objekt!! 13 Arrays.doc, V67 © H. Diethelm Seite 10/15 FHZ Hochschule für Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren 13 ARRAYS Die Klassenmethode System.arraycopy() ermöglicht ein effizientes Kopieren von einem Quellen-Array (src) in ein bereits existierendes Destionation-Array (dst). Ihr Methodenkopf ist wie folgt deklariert: static void arraycopy(Object src, Object dst, int dstPos, int length) int srcPos, int[] a1 = {1, 2, 3, 4, 5}; int[] a2 = {7, 7, 7, 7}; System.arraycopy(a1, 2, a2, 1, 2); // a2 => {7, 3, 4, 7} Ein Kopieren bzw. Klonen ist auch mit Hilfe der Methode clone() möglich, die bekanntlich für alle Objekte verfügbar ist (siehe Klasse Object). Das Destination-Array wird dabei mit dem Klonen kreiert. Ihr Methodenkopf ist wie folgt deklariert: protected Object clone() int[] a1 = {1, 2, 3, 4, 5}; int[] a2 = (int[]) a1.clone(); // Cast ist zwingend! // a2 => {1, 2, 3, 4, 5} Achtung: Falls die Array-Komponenten Objekte sind, so werden nur die entsprechenden Referenzen kopiert!! Man spricht von "shallow-copy". 13 Arrays.doc, V67 © H. Diethelm Seite 11/15 FHZ Hochschule für Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren 13 ARRAYS 6 Beispiel zum Einsatz von Array und Maus import java.awt.*; import java.applet.*; import java.awt.event.*; public class Rainfall extends Applet implements ActionListener, MouseListener { private Table rainData; private TextField inputField; public void init() { rainData = new Table(); Label l = new Label("Enter number,press ENTER-key and then click component"); add(l); inputField = new TextField(10); add(inputField); inputField.addActionListener(this); this.addMouseListener(this); } public void paint(Graphics g) { rainData.display(g); } 13 Arrays.doc, V67 © H. Diethelm Seite 12/15 FHZ Hochschule für Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren 13 ARRAYS public void actionPerformed(ActionEvent e){ if (e.getSource() == inputField) { int newValue=Integer.parseInt( inputField.getText()); rainData.setValue(newValue); repaint(); } } // MouseListener implementation // all 5 methods needed public void mouseClicked (MouseEvent e){ int y=e.getY(); rainData.selectComponent(y); repaint(); } public public public public void void void void mousePressed (MouseEvent e){ } mouseReleased (MouseEvent e){ } mouseEntered (MouseEvent e){ } mouseExited (MouseEvent e){ } } class Table private private private private private private private private 13 Arrays.doc, V67 © H. Diethelm { int[] rain = {0,0,0,0,0,0,0}; int index; int newValue; int sum = 0; final final final final int int int int startX = 20; startY = 60; boxHeight = 20; boxWidth = 60; Seite 13/15 FHZ Hochschule für Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren 13 ARRAYS public void display(Graphics g) { int y = startY; for(int s = 0; s < rain.length; s++) { g.drawRect(startX, y, boxWidth, boxHeight); g.drawString( Integer.toString(rain[s]), startX, y + boxHeight*3/4); y=y+boxHeight; } addValues(); g.drawString("Total rainfall is " + sum, 100, 100); } public void selectComponent(int y) { index = (y - startY)/boxHeight; if ((index>=0) && (index<rain.length)) rain[index] = newValue; } public void setValue(int value) { newValue = value; } private void addValues() { sum = 0; for (int s=0; s < rain.length; s++) { sum = sum + rain[s]; } } } 13 Arrays.doc, V67 © H. Diethelm Seite 14/15 FHZ Hochschule für Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren 13 ARRAYS 7 Vector vs. Array Arrays zeichnen sich mitunter dadurch aus, dass der Zugriff auf eine bestimmte Komponente in konstanter Zeit (vgl. Ο(1)) und daher sehr effizient erfolgt. Leider kann die Länge eines Arrays nach seiner Erzeugung nicht mehr geändert werden. Abhilfe schafft die Klasse java.util.Vector. Die Klasse Vector liefert die Illusion eines beliebig grossen Arrays von Objekten, wobei die Indizes wiederum fest bei 0 beginnen. Wichtige Methoden der Klasse Vector sind: zum Instanzieren: Vector() Vector(int n) // Vector mit Länge n Vector(int n, int incr) // wächst bei Bedarf um // incr zum Hinzufügen: void addElement(Object o) void setElementAt(Object o, int index) void insertElementAt(Object o, int index) // Objekte mit höheren Indizes verschieben zum Abfragen: Object elementAt(int index) // liefert Referenz // (Objekt muss anschliessend gecastet werden!) boolean contains(Object o) int indexOf(Object o) //erster Index int lastIndexOf(Object o) // letzter Index int size() // liefert Anzahl Elemente int capacity() // aktuell Anzahl freie Plätze zum Entfernen: boolean removeElement(Object o) // sucht und // entfernt erstes Objekt o void removeAllElements() 13 Arrays.doc, V67 © H. Diethelm Seite 15/15