Algorithms
Kurz: Eine feste Abfolge von Schritten, um ein bestimmtes Problem zu lösen — in Java oft als Methode implementiert, die eine Collection oder ein Array verarbeitet.
Genauer: Java liefert viele Standardalgorithmen bereits fertig mit, z. B. Collections.sort(), Collections.binarySearch() oder Collections.max() — für gängige Aufgaben lohnt es sich selten, sie neu zu implementieren. Für eigene Algorithmen sind Zeit- und Platzkomplexität (Big-O-Notation) die zentralen Bewertungsmaßstäbe.
Im Detail
Ein Algorithmus ist zunächst sprachunabhängig — dieselbe Sortierlogik lässt sich in Java, Python oder C++ umsetzen. Java macht den Umgang mit Standardalgorithmen aber besonders bequem, weil die Klasse java.util.Collections (für Listen) und java.util.Arrays (für Arrays) die wichtigsten davon bereits eingebaut mitliefern:
List<Integer> zahlen = new ArrayList<>(List.of(5, 3, 8, 1, 9));
Collections.sort(zahlen); // [1, 3, 5, 8, 9]
int index = Collections.binarySearch(zahlen, 8); // 3 - nur auf sortierten Listen gültig!
int max = Collections.max(zahlen); // 9
Collections.reverse(zahlen); // [9, 8, 5, 3, 1]Bei eigenen Algorithmen ist die Zeitkomplexität (Big-O-Notation) der zentrale Bewertungsmaßstab: eine lineare Suche (O(n)) durchsucht im schlimmsten Fall jedes Element einmal, eine binäre Suche (O(log n)) auf sortierten Daten halbiert bei jedem Schritt den Suchraum und ist bei großen Datenmengen drastisch schneller — verlangt aber, dass die Daten vorher sortiert sind (was selbst wieder Zeit kostet, meist O(n log n)). Bei sehr häufigen Lookups auf denselben Daten lohnt sich oft eine passende Datenstruktur wie HashSet/HashMap (O(1) im Schnittsfall) statt eines Algorithmus, der jedes Mal neu über eine Liste iteriert.
Eigene Algorithmen implementieren
Wenn kein Standardalgorithmus passt, lässt sich ein eigener meist iterativ oder rekursiv umsetzen. Eine lineare Suche als Beispiel:
static int linearSearch(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) return i;
}
return -1; // nicht gefunden
}Für rekursive Algorithmen (z. B. Quicksort oder eine eigene Fibonacci-Implementierung) gilt dieselbe Vorsicht wie bei Recursion allgemein: ohne klaren Abbruchfall droht ein StackOverflowError.
Häufige Fallstricke
Ein klassischer Anfängerfehler ist Collections.binarySearch() auf einer UNsortierten Liste aufzurufen — die Methode liefert dann ein undefiniertes, meist falsches Ergebnis, ohne eine Exception zu werfen. Ebenso häufig: Collections.sort() auf einer mit List.of(...) erzeugten unveränderlichen Liste versuchen, was eine UnsupportedOperationException auslöst (deshalb im Beispiel oben der Umweg über new ArrayList<>(List.of(...))).
Vergleich zu verwandten Konzepten
Ein Algorithmus beschreibt WIE ein Problem gelöst wird, eine Datenstruktur WIE die Daten dabei organisiert sind — beide hängen eng zusammen, da die Wahl der Struktur oft direkt die mögliche Effizienz des Algorithmus bestimmt (z. B. Suche in einem sortierten Array vs. in einer HashMap).
Siehe auch: Sorting, Recursion, Data Structures