© APSIS GmbH extern.gif (1249 Byte), Polling, 2000


Programmfehler

in der ersten Auflage des Lehrbuchs Programmieren mit Java

Stand: 19. Oktober 1999


Seite 136 (Kapitel 6.4.3, Programm 6.22)

In der 15. Zeile des Programms soll die Ausnahme vom Typ VollAusn einen anderen Namen, z.B. a haben:

catch(VollAusn a) {

und nicht wie im Buch

catch(VollAusn ausnahme) {

Seite 143 (Kapitel 6.5.6, Programm 6.28)

Am Ende der 5. Zeile auf der Seite fehlt ein Strichpunkt. Somit ist die Anweisung richtig:

ActionListener lauscher11 = new ActionListener() { // anonyme Klasse
	public void actionPerformed(ActionEvent ereignis) {
		... // Antwort auf die Menüauswahl
	}
};

und nicht wie im Buch

ActionListener lauscher11 = new ActionListener() { // anonyme Klasse
	public void actionPerformed(ActionEvent ereignis) {
		... // Antwort auf die Menüauswahl
	}
}

Seite 148 (Kapitel 7.1.3, Programm 7.5)

Die vorletzte und drittvorletzte Zeile des Programms müssen vertauscht werden (die globale Variabe attrappe muß außerhalb der Methode inhalt vereinbart werden). Die letzten drei Zeilen der Klasse EinEimer sind somit

	}
	private static Gefuellt attrappe;
}

und nich wie im Buch:

	private static Gefuellt attrappe;
	}
}

Seite 177/178 (Kapitel 8.1.6, Programm 8.8)

Der Parametertyp des Konstruktors MengeGen (letzte Zeile auf der Seite 177) und der Methode fuellen (2. Zeile auf der Seite 178) ist nicht Element sondern Object. Somit sind die aufgeführten Zeilen der Klassenvereinbarung von MengeGen

class MengeGen implements Menge { // (8.8)
	public MengeGen(final Object element) { ... } // merkt Klasse von element
	public MengeGen(final MengeGen menge) { ... } // like menge
	public void fuellen(final Object element) { ... } // like element

und nich wie im Buch:

class MengeGen implements Menge { // (8.8)
	public MengeGen(final Element element) { ... } // merkt Klasse Element von element
	public MengeGen(final MengeGen menge) { ... } // like menge
	public void fuellen(final Element element) { ... } // like element

Seite 197 (Kapitel 9.2.1)

Im ersten Programmstück auf der Seite sollen die Indizes der Reihung zweiEimer nicht 1 und 2 sondern 0 und 1 heißen:

zweiEimer[0] = new Eimer();
zweiEimer[1] = new Eimer();
public void linksFuellen() throws VollAusn {
	zweiEimer[0].fuellen();
}
public void rechtsFuellen() throws VollAusn {
	zweiEimer[1].fuellen();
}

und nicht wie im Buch

zweiEimer[1] = new Eimer();
zweiEimer[2] = new Eimer();
public void linksFuellen() throws VollAusn {
	zweiEimer[1].fuellen();
}
public void rechtsFuellen() throws VollAusn {
	zweiEimer[2].fuellen();
}

In der Mitte der Seite steht der Konstruktor Reihung. In der zweiten Zeile des Rumpfs sollen die runden Klammern ( und ) auf eckige [ und ] ausgetauscht werden:

public void Reihung(int laenge) {
	reihung = new Element[laenge];
}

und nicht wie im Buch

public void Reihung(int laenge) {
	reihung = new Element(laenge);
}

Seite 210 (Kapitel 9.3.5, Programm 9.12)

Im Hauptstrang des Methodenrumpfs eintragen fehlt die letzte Zeile:

juengste = neu;

Außerdem ist es überflüssig, den neuen Knoten zuerst mit einer verbindung-Komponente zu erzeugen, dann aber diese zurückzusetzen; es ist einfacher, die verbindung-Komponente gleich auf null zu setzen:

neu = new Knoten(element, null); // throws OutOfMemoryError

Die Methode ist also richtig:

public void eintragen (final Object element) throws VollAusn {
	try {
		neu = aelteste.verbindung;
		// throws NullPointerException im Sonderfall, wenn Warteschlange noch leer
		neu = new Knoten(element, null); // throws OutOfMemoryError
		juengste.verbindung = neu; // neuer jüngster Knoten wird eingefügt
		juengste = neu;
	}
	...

und nicht wie im Buch

public void eintragen (final Object element) throws VollAusn {
	try {
		neu = aelteste.verbindung;
		// throws NullPointerException im Sonderfall, wenn Warteschlange noch leer
		neu = new Knoten(element, aelteste.verbindung); // throws OutOfMemoryError
		neu.verbindung = null; // zurücksetzen
		juengste.verbindung = neu; // neuer jüngster Knoten wird eingefügt
	}
	...

Seite 233/234 (Kapitel 10.3.2, Programm 10.24)

Die Prozedur bruchzahlLesen wirft die Ausnahme java.io.IOException (vom System.in.read-Aufruf in der 4. Zeile) aus. Die Variable i in der viertletzten Zeile muß auch außerhalb der Schleife vereinbart werden. In der drittletzten Zeile heißt der Parameter des String-Konstruktors nicht buffer, sondern puffer. Somit ist die Methode richtig

public static float bruchzahlLesen() throws java.io.IOException { // liest float-Wert // (10.24)
	StringBuffer puffer = new StringBuffer(); // Puffer, Eingabe zu sammeln
	while (true) {
		int i = System.in.read(); // ein Zeichen lesen
		char c = (char)i; // Zeichen konvertieren
		if (c == '\n' || c == '\r') break; // Ende der Zeile? ¬
		puffer.append(c); // neues Zeichen am Ende des Puffers hinzufügen
	}
	int i = System.in.read(); // Rest der Eingabe verwerfen
	Float f = new Float(0).valueOf(new String(puffer)); // konvertieren
	return f.floatValue(); // float-Wert herauslesen
}

und nicht wie im Buch

public static float bruchzahlLesen() { // liest float-Wert // (10.24)
	StringBuffer puffer = new StringBuffer(); // Puffer, Eingabe zu sammeln
	while (true) {
		int i = System.in.read(); // ein Zeichen lesen
		char c = (char)i; // Zeichen konvertieren
		if (c == '\n' || c == '\r') break; // Ende der Zeile? ¬
		puffer.append(c); // neues Zeichen am Ende des Puffers hinzufügen
	}
	i = System.in.read(); // Rest der Eingabe verwerfen
	Float f = new Float(0).valueOf(new String(buffer)); // konvertieren
	return f.floatValue(); // float-Wert herauslesen
}

Seite 235 (Kapitel 10.3.6, Programm 10.28)

Beim 3. Parameter ausgabe der Methode mischen ist es sinnvoll, final wegzulassen, um anzudeuten, dass die Datei mit dem Namen ausgabe verändert wird:

final String eingabe1, final String eingabe2, String ausgabe) {

und nicht wie im Buch

final String eingabe1, final String eingabe2, final String ausgabe) {

In den 9., 10., 14., 18., 24 und 28. Zeilen des Programms soll für die Dateiobjekte band1 und band2 jeweils nicht die Methode write, sondern die Methode read aufgerufen werden. Somit lautet die Methode richtig

public void mischen( // vorsortierte Dateien werden gemischt // (10.28)
		final String eingabe1, final String eingabe2, String ausgabe) {
	IFile band1 = new IFile(), band2 = new IFile();
	OFile band3 = new OFile();
	Element puffer1 = new Element(), puffer2 = new Element(); // geordnet
	band1.open(eingabe1);
	band2.open(eingabe2);
	band3.open(ausgabe);
	band1.read(puffer1);
	band2.read(puffer2);
	while (!band1.eof() && !band2.eof()) {
		if (puffer1.kleiner(puffer2)) { // Operation für Element
			band3.write(puffer1); // den kleineren ausschreiben
			band1.read(puffer1); // und wieder einlesen
		}
		else {
			band3.write(puffer2);
			band2.read(puffer2);
		}
	} // band1 oder band2 ist zu Ende
	// Rest kopieren:
	while (!band1.eof()) {
		band3.write(puffer1);
		band1.read(puffer1);
	}
	while (!band2.eof()) {
		band3.write(puffer2);
		band2.read(puffer2);
	}
}

und nicht wie im Buch

public void mischen( // vorsortierte Dateien werden gemischt // (10.28)
		final String eingabe1, final String eingabe2, final String ausgabe) {
	IFile band1 = new IFile(), band2 = new IFile();
	OFile band3 = new OFile();
	Element puffer1 = new Element(), puffer2 = new Element(); // geordnet
	band1.open(eingabe1);
	band2.open(eingabe2);
	band3.open(ausgabe);
	band1.write(puffer1);
	band2.write(puffer2);
	while (!band1.eof() && !band2.eof()) {
		if (puffer1.kleiner(puffer2)) { // Operation für Element
			band3.write(puffer1); // den kleineren ausschreiben
			band1.write(puffer1); // und wieder einlesen
		}
		else {
			band3.write(puffer2);
			band2.write(puffer2);
		}
	} // band1 oder band2 ist zu Ende
	// Rest kopieren:
	while (!band1.eof()) {
		band3.write(puffer1);
		band1.write(puffer1);
	}
	while (!band2.eof()) {
		band3.write(puffer2);
		band2.write(puffer2);
	}
}

Noch besser ist es aber, die Methode mischen mit Hilfe der schon im Kapitel 8.3.8 auf Seite 189 eingeführten Multibehälter lehrbuch.kapitel8.SeqDatei vorzustellen.


Seite 249 (Kapitel 11.2.2, Programm 11.6)

In der dritten Zeile des Programms fehlt der Index:

for (int i = 0; i < gedaechtnis.length; i++) gedaechtnis[i] = 0; // vorbesetzen

und nicht wie im Buch

for (int i = 0; i < gedaechtnis.length; i++) gedaechtnis = 0; // vorbesetzen

Seite 250 (Kapitel 11.3.2, Programm 11.12)

In der ersten Zeile des Konstruktors ShellSort müssen Kommentarzeichen hinzugefügt werden.

Es heißt also richtig

public ShellSort(Element[] daten, int[] k) { // Schrittweiten in k

und nicht wie im Buch

public ShellSort(Element[] daten, int[] k) { Schrittweiten in k

Seite 266 (Kapitel 11.4.4, Programm 11.22, Methode loeschen)

In der 7. Zeile von unten soll nicht die Methode loesch, sondern die Methode loeschen (rekursiv) aufgerufen werden:

astGekuerzt = knoten.rechts.loeschen(kleinster.knoten.wert);

und nicht wie im Buch

astGekuerzt = knoten.rechts.loesch(kleinster.knoten.wert);

In der 10. Zeile der Methode loeschen soll die geschweifte Klammer gestrichen werden:

else if (knoten.zaehler > 1) // element.gleich(knoten.wert) // element gefunden

und nicht wie im Buch

else if (knoten.zaehler > 1) { // element.gleich(knoten.wert) // element gefunden

Seite 267 (Kapitel 11.4.4, Programm 11.22, Methode loeschen)

In der letzten Zeile des Programms soll void auf boolean ausgetauscht werden:

private boolean rechtsAusgleichen() { ... } // symmetrisch

und nicht wie im Buch

private void rechtsAusgleichen() { ... } // symmetrisch

Seite 287 (Kapitel 13.1.4, Programm 13.4, Methode loeschen)

In der zweiten Zeile des zweiten Programmabschnitt auf der Seite soll werkzeugkiste auf getToolkit() ausgetauscht werden:

try {
	Image meinBild = getToolkit().getImage(
	new URL("file:/laufwerk:/[Pfad]/balloons.gif"));
	grafik.drawImage(meinBild, 5,40, this); // y groß genug wählen, sonst unsichtbar
} catch (MalformedURLException e) { System.err.println(e); }

und nicht wie im Buch

try {
	Image meinBild = werkzeugkiste.getImage(
	new URL("file:/laufwerk:/[Pfad]/balloons.gif"));
	grafik.drawImage(meinBild, 5,40, this); // y groß genug wählen, sonst unsichtbar
} catch (MalformedURLException e) { System.err.println(e); }

© APSIS GmbH extern.gif (1249 Byte), Polling, 2000