Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 17 additions & 21 deletions docs/additional-material/tools/debugging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,15 @@ Laufzeit- und logische Fehler den Einsatz eines _Debuggers_.

Ein Debugger ermöglicht es, ein Programm kontrolliert auszuführen, an beliebigen
Stellen anzuhalten und den Zustand von Variablen sowie den Programmfluss zu
inspizieren. Moderne IDEs wie [Eclipse](https://eclipseide.org/) oder
[IntelliJ IDEA](https://www.jetbrains.com/idea/) verfügen über einen
integrierten Debugger.
inspizieren. [Eclipse](https://eclipseide.org/) verfügt über einen integrierten
Debugger.

## Weiterführende Links

Die folgenden Ressourcen bieten eine vertiefte Einführung in das Debugging mit
den gängigsten Java-IDEs.
Eclipse.

- [Eclipse Debugging Guide](https://www.eclipse.org/community/eclipse_newsletter/2017/june/article1.php)
- [IntelliJ IDEA – Debug Code](https://www.jetbrains.com/help/idea/debugging-code.html)
- [Visualizing Execution with Java Visualizer](https://pythontutor.com/java.html)

## Breakpoints
Expand Down Expand Up @@ -74,10 +72,10 @@ zu verfolgen.
<Tabs>
<TabItem value="a" label="Step Over" default>

**Step Over** (`F6` in Eclipse / `F8` in IntelliJ) führt die aktuelle Zeile
vollständig aus und hält in der nächsten Zeile derselben Methode an.
Methodenaufrufe werden dabei als ein Schritt behandelt – der Debugger springt
nicht in die aufgerufene Methode hinein.
**Step Over** (`F6`) führt die aktuelle Zeile vollständig aus und hält in der
nächsten Zeile derselben Methode an. Methodenaufrufe werden dabei als ein
Schritt behandelt – der Debugger springt nicht in die aufgerufene Methode
hinein.

```java title="Beispiel" showLineNumbers
int a = 5; // <- Debugger hält hier an
Expand All @@ -88,9 +86,8 @@ int c = b * 2; // <- Debugger hält hier an nach Step Over
</TabItem>
<TabItem value="b" label="Step Into">

**Step Into** (`F5` in Eclipse / `F7` in IntelliJ) springt in den Rumpf des
Methodenaufrufs in der aktuellen Zeile hinein, sodass dessen Ausführung Schritt
für Schritt verfolgt werden kann.
**Step Into** (`F5`) springt in den Rumpf des Methodenaufrufs in der aktuellen
Zeile hinein, sodass dessen Ausführung Schritt für Schritt verfolgt werden kann.

```java title="Beispiel" showLineNumbers
int a = 5; // <- Debugger hält hier an
Expand All @@ -101,16 +98,16 @@ int c = b * 2;
</TabItem>
<TabItem value="c" label="Step Return">

**Step Return** (`F7` in Eclipse / `Shift+F8` in IntelliJ) führt die restliche
aktuelle Methode vollständig aus und hält nach der Rückkehr in der aufrufenden
Methode an. Dieser Befehl wird typischerweise eingesetzt, wenn man versehentlich
in eine Methode hineingesprungen ist.
**Step Return** (`F7`) führt die restliche aktuelle Methode vollständig aus und
hält nach der Rückkehr in der aufrufenden Methode an. Dieser Befehl wird
typischerweise eingesetzt, wenn man versehentlich in eine Methode
hineingesprungen ist.

</TabItem>
<TabItem value="d" label="Resume">

**Resume** (`F8` in Eclipse / `F9` in IntelliJ) setzt die Programmausführung
fort, bis der nächste Breakpoint erreicht wird oder das Programm regulär endet.
**Resume** (`F8`) setzt die Programmausführung fort, bis der nächste Breakpoint
erreicht wird oder das Programm regulär endet.

</TabItem>
</Tabs>
Expand All @@ -122,15 +119,14 @@ angegebene Bedingung wahr ist. Das ist besonders nützlich, wenn ein Fehler nur
unter bestimmten Umständen auftritt – etwa bei einem konkreten
Schleifendurchlauf oder einem bestimmten Parameterwert.

```java title="Example: Fehler tritt nur bei i == 42 auf" showLineNumbers
```java title="Beispiel: Fehler tritt nur bei i == 42 auf" showLineNumbers
for (int i = 0; i < 100; i++) {
process(i); // <- bedingter Breakpoint: i == 42
}
```

In Eclipse wird ein bedingter Breakpoint über **Rechtsklick auf den Breakpoint →
Breakpoint Properties → Enable Condition** gesetzt. In IntelliJ IDEA über
**Rechtsklick auf den Breakpoint → More → Condition**.
Breakpoint Properties → Enable Condition** gesetzt.

## Häufige Fehler und deren Ursachen

Expand Down
24 changes: 6 additions & 18 deletions docs/documentation/algorithms.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,9 @@ Im nachfolgenden Beispiel wird die Zahlenfolge

:::info

l = linke Grenze, r = rechte Grenze, m = Mitte

:::

:::info

Bei der Ermittlung der Mitte wird i.d.R. die Abrundungsfunktion verwendet, d.h.
zu einer reellen Zahl wird die größte ganze Zahl, die kleiner als die reelle
Zahl ist, verwendet.
l = linke Grenze, r = rechte Grenze, m = Mitte. Bei der Ermittlung der Mitte
wird die Abrundungsfunktion verwendet, d.h. es wird die größte ganze Zahl
kleiner als die reelle Zahl verwendet.

:::

Expand Down Expand Up @@ -290,15 +284,9 @@ auf beide Teile angewendet (Teile-und-Herrsche-Prinzip).
:::info

l = linke Grenze, r = rechte Grenze, m = Mitte, d = Datensammlung, i = linker
Index, j = rechter Index

:::

:::info

Bei der Ermittlung der Mitte wird i.d.R. die Abrundungsfunktion verwendet, d.h.
zu einer reellen Zahl wird die größte ganze Zahl, die kleiner als die reelle
Zahl ist, verwendet.
Index, j = rechter Index. Bei der Ermittlung der Mitte wird die
Abrundungsfunktion verwendet, d.h. es wird die größte ganze Zahl kleiner als die
reelle Zahl verwendet.

:::

Expand Down
37 changes: 30 additions & 7 deletions docs/documentation/arrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,10 @@ public class MainClass {
}
```

:::info

Der Index beginnt in Java bei 0.

:::

## Der Parameter _String[] args_

Der Parameter `String[] args` der main-Methode ermöglicht es, der Anwendung beim
Aufruf über die Kommandozeile Argumente zu übergeben.
Aufruf über die [Kommandozeile](java) Argumente zu übergeben.

```java title="MainClass.java" showLineNumbers
public class MainClass {
Expand Down Expand Up @@ -113,3 +107,32 @@ public class MainClass {
Technisch gesehen handelt es sich bei einer variablen Argumentliste um ein Feld.

:::

## Mehrdimensionale Felder

Mehrdimensionale Felder sind Felder, deren Elemente selbst wieder Felder sind.
Der häufigste Anwendungsfall ist das zweidimensionale Feld, das sich als Matrix
mit Zeilen und Spalten vorstellen lässt. Der Zugriff auf ein Element erfolgt
über zwei Indizes: zuerst die Zeile, dann die Spalte.

```java title="MainClass.java" showLineNumbers
public class MainClass {

public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

// alle Elemente zeilenweise ausgeben
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
System.out.print(matrix[row][col] + " ");
}
System.out.println();
}
}

}
```
2 changes: 1 addition & 1 deletion docs/documentation/binary-numbers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Informationen wie Zahlen und Zeichen werden im Computer in Form von sogenannten
_Bits_ (Binary Digits) gespeichert. Ein Bit ist die kleinstmögliche
Informationseinheit und kann zwei Zustände annehmen: 0 und 1 (bzw. „an" und
„aus", „wahr" und „falsch", „Strom fließt" und „Strom fließt nicht"). Zahlen,
die mit Hilfe von Bits dargestellt werden, nennt man _Binärzahlen_, das
die mithilfe von Bits dargestellt werden, nennt man _Binärzahlen_, das
dazugehörige Zahlensystem _Binärsystem_. Zahlensysteme legen fest, wie Zahlen
dargestellt werden — der Name verrät dabei jeweils, wie viele Ziffern zur
Verfügung stehen. Um Verwechslungen zu vermeiden, können Zahlen mit einem nach-
Expand Down
18 changes: 9 additions & 9 deletions docs/documentation/class-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ tags: [class-structure]
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

Klassen stellen den grundlegenden Rahmen für Programme dar. Jede Klasse kann
Daten (_Attribute_) und Routinen (_Methoden_) besitzen. Routinen bestehen aus
Folgen von verzweigten und sich wiederholenden Anweisungen, wobei Anweisungen
Klassen sind der grundlegende Rahmen für Programme. Jede Klasse kann Daten
(_Attribute_) und Routinen (_Methoden_) besitzen. Routinen bestehen aus Folgen
von verzweigten und sich wiederholenden Anweisungen, wobei Anweisungen
wohldefinierte Befehle darstellen, die der Interpreter zur Laufzeit ausführt.
Anweisungen müssen in Java mit einem Semikolon abgeschlossen werden und können
zu Anweisungsblöcken zusammengefasst werden, die durch geschweifte Klammern
Expand Down Expand Up @@ -103,10 +103,10 @@ bezeichnet.
## Die main-Methode

Die Methode `void main(args: String[])` ist eine spezielle Methode in Java und
stellt Startpunkt sowie Endpunkt einer Anwendung bzw. eines Programms dar. Nur
Klassen mit einer main-Methode können von der Laufzeitumgebung ausgeführt
werden. Aus diesem Grund werden Klassen mit einer main-Methode auch als
_ausführbare Klassen_ oder als _Startklassen_ bezeichnet.
ist Startpunkt sowie Endpunkt einer Anwendung. Nur Klassen mit einer
main-Methode können von der Laufzeitumgebung ausgeführt werden. Aus diesem Grund
werden Klassen mit einer main-Methode auch als _ausführbare Klassen_ oder als
_Startklassen_ bezeichnet.

```java title="MainClass.java" showLineNumbers
public class MainClass {
Expand Down Expand Up @@ -162,8 +162,8 @@ Einsatz von Quellcode-Kommentaren i.d.R. verzichtet werden sollte.
## Entwicklungspakete

Entwicklungspakete ermöglichen das hierarchische Strukturieren von Klassen. Um
die Klassen eines Entwicklungspaketes verwenden zu können, müssen die jeweiligen
Klassen explizit mit Hilfe des Schlüsselworts `import` importiert werden.
die Klassen eines Entwicklungspaketes verwenden zu können, müssen sie mit dem
Schlüsselwort `import` importiert werden.

```mermaid
flowchart
Expand Down
4 changes: 2 additions & 2 deletions docs/documentation/data-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ public class MainClass {

Der Cast-Operator `()` erlaubt die explizite Umwandlung eines Datentyps in einen
anderen. Bei Wertzuweisungen findet außerdem eine implizite Typumwandlung vom
niederwertigen zum höherwertigen Datentyp statt. Zu beachten ist, dass bei einer
Typumwandlung ein Genauigkeitsverlust auftreten kann.
niederwertigen zum höherwertigen Datentyp statt. Bei einer Typumwandlung kann
ein Genauigkeitsverlust auftreten.

```java title="MainClass.java" showLineNumbers
public class MainClass {
Expand Down
45 changes: 45 additions & 0 deletions docs/documentation/exceptions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ classDiagram
RunTimeException <|-- ArithmeticException
```

Eine Übersicht wichtiger Ausnahmenklassen findet sich in der
[Java API](java-api).

## Definition von Ausnahmenklassen

Eigene Ausnahmenklassen werden durch Ableitung von einer bestehenden
Expand Down Expand Up @@ -133,3 +136,45 @@ public class MainClass {

}
```

## Der finally-Block

Der optionale `finally`-Block wird nach dem `try`- und allen `catch`-Blöcken
immer ausgeführt — unabhängig davon, ob eine Ausnahme aufgetreten ist oder
nicht. Er eignet sich daher für Aufräumarbeiten wie das Schließen von
Ressourcen.

```java title="MainClass.java" showLineNumbers
public class MainClass {

public static void main(String[] args) {
try {
Notebook notebook = new Notebook("Mein Gaming Laptop", new Cpu(4.7, 8), 32, 16);
} catch (InvalidValueException e) {
System.err.println(e.getMessage());
} finally {
System.out.println("wird immer ausgeführt");
}
}

}
```

Werden Ressourcen wie Dateiströme geöffnet, empfiehlt sich statt `finally` die
_Try-with-Resources_-Anweisung. Klassen, die `AutoCloseable` implementieren,
werden dabei am Ende des `try`-Blocks automatisch geschlossen — auch im
Fehlerfall.

```java title="MainClass.java" showLineNumbers
public class MainClass {

public static void main(String[] args) {
try (FileReader reader = new FileReader("data.txt")) {
// Datei lesen
} catch (IOException e) {
System.err.println(e.getMessage());
}
}

}
```
46 changes: 46 additions & 0 deletions docs/documentation/hashing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,49 @@ einer Suche wird zuerst der Bucket bestimmt, dann der Bucket durchsucht.

</TabItem>
</Tabs>

## Hashing in Java

Java verwendet Hashing intern in den Klassen [`HashMap<K, V>`](maps) und
[`HashSet<E>`](java-collections-framework). Der Schlüssel eines Eintrags
bestimmt über seinen Hashcode den Bucket, in dem der Eintrag abgelegt wird. Bei
einer Suche wird zunächst der Bucket über den Hashcode gefunden, anschließend
wird innerhalb des Buckets mit `equals()` verglichen.

Damit diese Mechanismen korrekt funktionieren, müssen die Methoden `hashCode()`
und `equals()` der [Klasse `Object`](object) konsistent überschrieben werden:

- Zwei inhaltlich gleiche Objekte (`equals()` gibt `true` zurück) müssen
**denselben Hashcode** liefern.
- Zwei Objekte mit demselben Hashcode müssen **nicht** inhaltlich gleich sein
(eine Kollision ist erlaubt, aber ineffizient).

```java title="Person.java (Auszug)" showLineNumbers
public class Person {

private String name;
private int age;

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
Person other = (Person) object;
return age == other.age && Objects.equals(name, other.name);
}

@Override
public int hashCode() {
return Objects.hash(name, age);
}

}
```

:::warning

Wird `equals()` überschrieben, ohne `hashCode()` anzupassen, verhält sich die
Klasse in `HashMap` und `HashSet` falsch: Zwei inhaltlich gleiche Objekte landen
in unterschiedlichen Buckets und werden nicht als gleich erkannt.

:::
10 changes: 9 additions & 1 deletion docs/documentation/interfaces.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public class Smartphone implements MobileDevice {

@Override
public int getScreenSizeInInches() {
return Math.sqrt(Math.pow(widthInInches) + Math.pow(heightInInches));
return (int) Math.sqrt(Math.pow(widthInInches, 2) + Math.pow(heightInInches, 2));
}
...
}
Expand Down Expand Up @@ -178,3 +178,11 @@ public class MainClass {

</TabItem>
</Tabs>

:::tip

Eine Schnittstelle eignet sich, wenn mehrere, voneinander unabhängige Klassen
dasselbe Verhalten teilen sollen. Eine [abstrakte Klasse](abstract-and-final)
eignet sich, wenn gemeinsame Implementierungen geerbt werden sollen.

:::
2 changes: 1 addition & 1 deletion docs/documentation/java-stream-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ intermediäre Operationen sind Filtern, Abbilden und Sortieren.
| Operation | Methode | Schnittstellen-Methode |
| ------------- | ---------------------------------------------------------- | -------------------------------- |
| Filtern | `Stream<T> filter(predicate: Predicate<T>)` | `boolean test(t: T)` |
| Abbilden | `Stream<T> map(mapper: Function<T, R>)` | `R apply(t: T)` |
| Abbilden | `Stream<R> map(mapper: Function<T, R>)` | `R apply(t: T)` |
| Abbilden | `DoubleStream mapToDouble(mapper: ToDoubleFunction<T, R>)` | `double applyAsDouble(value: T)` |
| Abbilden | `IntStream mapToInt(mapper: ToIntFunction<T, R>)` | `int applyAsInt(value: T)` |
| Abbilden | `LongStream mapToLong(mapper: ToLongFunction<T, R>)` | `long applyAsLong(value: T)` |
Expand Down
Loading
Loading