Alle Tabs der Lerneinheit (Erklärung · Interaktiv · Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
Erklärung
Ein String ist eine Zeichenkette, also eine geordnete Folge von Buchstaben, Ziffern und Sonderzeichen. Du lernst hier Strings in Java und Python zu lesen, zu vergleichen, zu schneiden, zu suchen und sicher zu verändern. Besonders wichtig sind 0-basierte Indizes, exklusives end bei substring/slicing, Immutability, Java .equals() statt ==, Regex-Fallen bei split und Performance-Probleme bei wiederholter Konkatenation (StringBuilder vs +). Pflichtstoff im 1. Semester Informatik und Wirtschaftsinformatik.
Die wichtigsten Operationen, die du in der Klausur kennen musst:
- Länge:
s.length()in Java,len(s)in Python - Zugriff:
s.charAt(i)(Java) oders[i](Python), null-basiert - Vergleich:
s.equals(other)in Java (==vergleicht Referenzen!),s == otherin Python - Suche:
s.contains(x),s.indexOf(x),s.startsWith(x) - Splitten / Verbinden:
s.split(",")undString.join(",", arr) - Immutability: Strings sind in Java unveränderlich,
s.replace()gibt neuen String zurück
In Klausuren ist die häufigste Falle: s == "hallo" in Java vergleicht Referenzen, nicht den Inhalt. Immer s.equals("hallo") benutzen. Plus: Off-by-one bei charAt(s.length()) wirft StringIndexOutOfBoundsException.
Das Problem
Du musst:
- prüfen ob eine E-Mail ein "@" enthält
- den Vornamen aus "Vorname Nachname" rausholen
- alle Großbuchstaben kleinschreiben
- ein Passwort auf Länge ≥ 8 testen
Alle vier Aufgaben sind String-Manipulation. Die meisten Klausurfragen in den ersten Programmierwochen drehen sich darum.
Ein String ist eine Sequenz von Zeichen, wie ein Array von Buchstaben. In Java:
String. In Python:str.
Strings sind indexiert (0-basiert)
Index: 0 1 2 3 4
Zeichen: H a l l o
Das erste Zeichen hat Index 0, das letzte Index length − 1. Klassisches Off-by-one-Problem.
String s = "Hallo";
System.out.println(s.length()); // 5
System.out.println(s.charAt(0)); // 'H'
System.out.println(s.charAt(4)); // 'o'
System.out.println(s.charAt(5)); // !! StringIndexOutOfBoundsException
In Python geht's mit Klammern wie bei Listen:
s = "Hallo"
print(len(s)) # 5
print(s[0]) # 'H'
print(s[-1]) # 'o' (von hinten zählen)
print(s[5]) # IndexError
Python erlaubt negative Indizes,
s[-1]ist das letzte Zeichen,s[-2]das vorletzte. Java nicht.
Die wichtigsten String-Operationen
Länge
"Hallo".length() // 5
len("Hallo") # 5
Substring / Slicing
Bekommst einen Teil-String. Achtung: der Endindex ist EXKLUSIV (er markiert die erste Position, die NICHT mehr dazugehört). Kurzform: "end ist exklusiv".
String s = "Hallo Welt";
s.substring(0, 5); // "Hallo" (Index 0,1,2,3,4, NICHT 5)
s.substring(6, 10); // "Welt"
s.substring(6); // "Welt" (ohne end → bis zum Ende)
s = "Hallo Welt"
s[0:5] # "Hallo"
s[6:10] # "Welt"
s[6:] # "Welt" (ohne end → bis Ende)
s[:5] # "Hallo" (ohne start → ab Anfang)
Python-Slicing ist mächtiger:
s[::2]jedes zweite,s[::-1]reversed.
Konkatenation: +
"Hallo" + " " + "Welt" // "Hallo Welt"
"Hallo" + " " + "Welt" # "Hallo Welt"
Suchen: indexOf / find
"Hallo Welt".indexOf("Welt") // 6
"Hallo Welt".indexOf("xyz") // -1 (nicht gefunden)
"Hallo Welt".find("Welt") # 6
"Hallo Welt".find("xyz") # -1
"Welt" in "Hallo Welt" # True (einfacher!)
Ersetzen: replace
"Hallo Welt".replace("Welt", "Du") // "Hallo Du"
"Hallo Welt".replace("Welt", "Du") # "Hallo Du"
Groß/Klein
"Hallo".toUpperCase() // "HALLO"
"Hallo".toLowerCase() // "hallo"
"Hallo".upper() # "HALLO"
"Hallo".lower() # "hallo"
Splitten + Joinen
String[] parts = "a,b,c".split(","); // ["a", "b", "c"]
String joined = String.join("-", parts); // "a-b-c"
parts = "a,b,c".split(",") # ["a", "b", "c"]
joined = "-".join(parts) # "a-b-c"
Java-Falle:
String.splitnimmt einen regulären Ausdruck, nicht einen wörtlichen Trenner. Bei Regex-Sonderzeichen wie.,|,?,*,+muss man escapen oderPattern.quote(...)verwenden.
CSV-Hinweis:
split(",")reicht nur für einfache kommagetrennte Strings ohne Quotes/Escaping. Echtes CSV mit Anführungszeichen, Kommas in Feldern und Newlines braucht eine CSV-Bibliothek.
Strings sind immutable
In Java und Python sind Strings unveränderlich. Jede Operation liefert einen neuen String, der Original bleibt.
String s = "hallo";
s.toUpperCase(); // gibt "HALLO" zurück, aber...
System.out.println(s); // "hallo", s unverändert!
s = s.toUpperCase(); // muss neu zugewiesen werden
System.out.println(s); // "HALLO"
s = "hallo"
s.upper() # gibt "HALLO" zurück...
print(s) # "hallo", s unverändert!
s = s.upper() # muss neu zugewiesen werden
print(s) # "HALLO"
Klausur-Falle:
s.toUpperCase()allein verändert nichts, du musst das Ergebnis wieder zuweisen.
Warum immutable?
- Hashing (für HashMap-Keys): mutable Schlüssel würden den Hash kaputt machen
- Sicherheit (Strings als Pfade, URLs): kein nachträgliches Verfälschen
- Performance: Strings können geteilt werden ohne Defensive-Kopien
Achtung bei vielen Konkatenationen
Bei wiederholtem s = s + ... in einer Schleife wird der bisherige Inhalt immer wieder in neue String-Ergebnisse kopiert. Einzelne Konkatenations-Ausdrücke außerhalb einer Schleife kann Java effizient umsetzen (intern via StringBuilder oder seit Java 9 invokedynamic/StringConcatFactory); problematisch ist erst das wiederholte Pattern in Schleifen. Bei 1000 Konkatenationen in einer Schleife → O(n²) Zeichen-Kopien. Dafür nimm StringBuilder.
// SCHLECHT, O(n²)
String s = "";
for (int i = 0; i < 1000; i++) {
s = s + i; // jedes mal neuer String
}
// GUT, O(n)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String s = sb.toString();
In Python: gleicher Trick mit Liste + "".join(...):
parts = []
for i in range(1000):
parts.append(str(i))
s = "".join(parts)
String-Vergleich: == vs equals
In Java EXTREMER Klausur-Klassiker:
String a = "Hallo";
String b = "Hallo";
String c = new String("Hallo");
a == b // ⚠ bei gleichen Literalen wegen Interning true, bei zur Laufzeit erzeugten Strings unzuverlässig
a == c // FALSE, anderes Objekt im Heap
a.equals(b) // true
a.equals(c) // true
Regel: Für Inhaltsvergleich in Java immer
.equals()verwenden, nicht==.==vergleicht die Referenz (zeigen beide Variablen auf dasselbe Objekt?),.equals()vergleicht den Inhalt.
In Python: == vergleicht den Inhalt, is vergleicht Referenzen.
a = "Hallo"
b = "Hallo"
a == b # True, vergleicht Inhalt (häufig richtig)
a is b # häufig True (Interning), aber UNVERLÄSSLICH
char vs. String
In Java unterscheidet man:
char c = 'A'; // einzelnes Zeichen in einfachen Anführungszeichen
String s = "A"; // String der Länge 1 in doppelten Anführungszeichen
charist ein primitiver Typ, ein 16-bit UTF-16 Code-Unit, nicht immer ein vollständiger Unicode-Codepoint. Viele Zeichen passen in ein einzelneschar, aber Emojis und andere supplementary characters bestehen aus zweichar-Werten (Surrogatpaar). Für echte Unicode-Codepoints nutzt man Methoden wies.codePointAt(i).Stringist ein Objekt;s.length()zählt char-Code-Units, nicht unbedingt sichtbare Zeichen oder Codepoints.
In Python gibt es keinen char-Typ, s[0] liefert wieder einen String der Länge 1.
s = "Hallo"
type(s[0]) # <class 'str'>
Klausur-Tricks
Trick 1, Off-by-one bei Indizes: Index läuft 0..length−1, nicht 1..length. s.charAt(s.length()) ist Exception.
Trick 2, substring(start, end) ist EXKLUSIV: "Hallo".substring(1, 4) → "all", NICHT "alli". Wenn du n Zeichen ab Position k willst → substring(k, k+n).
Trick 3, In Java IMMER .equals(), niemals == für String-Vergleich. Klausuren testen das jedes Semester.
Trick 4, Strings immutable: s.toUpperCase() allein ändert s nicht. s = s.toUpperCase().
Trick 5, indexOf liefert -1 wenn nicht gefunden: niemals an Index −1 zugreifen.
int i = s.indexOf("foo");
if (i != -1) {
s.charAt(i); // sicher
}
Trick 6, Palindrom-Klassiker: Diese beiden Klassiker (Palindrom und Anagramm unten) kombinieren Indexzugriff, Schleifen, Zeichen-Vergleich und ggf. Sortieren, daher tauchen sie oft als kleine Programmieraufgabe in Klausuren auf. Ein Palindrom ist ein String, der sich vorwärts wie rückwärts liest.
boolean isPalindrom(String s) {
return s.equals(new StringBuilder(s).reverse().toString());
}
// Smarter: zwei Pointer
boolean isPalindrom2(String s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (s.charAt(i) != s.charAt(j)) return false;
i++; j--;
}
return true;
}
Trick 7, Anagramm-Klassiker: zwei Strings sind Anagramme wenn sie dieselben Zeichen in beliebiger Reihenfolge enthalten.
boolean isAnagram(String a, String b) {
if (a.length() != b.length()) return false;
char[] ca = a.toCharArray();
char[] cb = b.toCharArray();
Arrays.sort(ca);
Arrays.sort(cb);
return Arrays.equals(ca, cb);
}
Trick 8, Whitespace und trim(): " Hallo ".trim() → "Hallo". Klausurfrage zur User-Eingabe-Säuberung.
Trick 9, Encoding: ASCII (128 Zeichen, 7 Bit) vs. UTF-8 (variable Länge, alle Sprachen). Java-Strings sind UTF-16-basiert: char ist eine 16-bit Code-Unit, nicht zwingend ein vollständiger Codepoint. s.length() zählt char-Code-Units, nicht sichtbare Zeichen, Emojis brauchen meist zwei chars (Surrogatpaar). Für echte Codepoint-Iteration: s.codePointAt(i) / s.codePoints().
Wo brauchst du Strings?
- User Input: jede Form, jedes Input-Feld liefert Strings
- APIs / JSON: alles wird über Strings serialisiert
- Datenbanken: SQL ist String, Spalten-Typen wie VARCHAR
- Logging / Debugging: jede Print-Ausgabe
- Pfade / URLs: alles strukturierter Text
- Validierung: Email, IBAN, PIN, Passwort, alles String-Check
Faustregel: Strings gehören zu den häufigsten Datentypen, mit denen du als Programmieranfänger arbeitest. Lerne die wichtigsten Methoden auswendig: substring, indexOf, replace, split, equals.
Interaktiv
String-Lab
Tipp einen String ein und probier die Operationen aus:
- Char-Boxen: jeder Buchstabe mit seinem Index, sieh wie 0-basiert funktioniert
- substring(start, end): zieh die Slider und beobachte den live-highlightet Bereich. end ist exklusiv!
- indexOf-Animation: gib einen Suchstring ein und klick "Suche starten", der Algorithmus prüft Schritt für Schritt jede Position
- Transformations-Buttons: toUpperCase, toLowerCase, reverse, trim, beachte: Original bleibt unverändert
Probier folgendes:
- "Hallo Welt", substring(6, 10) → "Welt"
- "racecar", substring(0, 4) → "race"
- indexOf("lo") in "Hallo Welt" → bei Index 3 gefunden, nachdem 4 Startpositionen geprüft wurden (jede Startposition kann mehrere Zeichenvergleiche brauchen)
- toUpperCase auf "Hallo" → "HALLO", aber "Hallo" daneben bleibt unverändert (Immutability!)
Interaktive Visualisierung
Live-Lab für String-Operationen (substring, indexOf, replace, split) mit Index-Highlight.
Faustregel zum Mitnehmen: Strings sind indexierte Zeichensequenzen, immutable, und end ist exklusiv. Drei Klausur-Klassiker auf einen Blick.
Code-Stepper: Klausur-Klassiker durchspielen
Drei interaktive Demos zu den häufigsten Klausur-Stolperern bei Strings: Immutability (eine Konkatenation überschreibt NICHT den alten String, sondern erzeugt einen neuen), == vs .equals() (Referenz vs Wert-Vergleich, der bekannteste Java-String-Klassiker) und StringBuilder vs String-Konkatenation in einer Schleife (O(n) vs O(n^2)). Klicke auf Step oder Auto.
1. String-Immutability: s = s + "x" überschreibt nichts
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
2. == vs .equals(): Referenz vs Wert
In Java vergleicht == Referenzen (zeigen beide auf dasselbe Objekt?), .equals() vergleicht Werte (haben beide denselben Inhalt?). Bei String-Literalen kommt der String-Pool ins Spiel und macht es noch verwirrender. Klausur-Klassiker.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
3. StringBuilder vs String-Konkatenation: O(n) vs O(n^2)
String-Konkatenation in einer Schleife mit + erzeugt jedes Mal ein neues String-Objekt und kopiert alle bisherigen Zeichen mit. Bei n Iterationen: O(n²) Zeichen-Kopien. StringBuilder baut den String über einen veränderbaren Puffer auf; der Gesamtaufwand ist linear in der Gesamtlänge der Ausgabe, append ist amortisiert effizient pro Aufruf. Klausur-Klassiker zur Komplexität.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
Quiz
Klausurfragen mit Lösungen (8)
- F1.Was gibt "Hallo".charAt(0) in Java zurück?
Antwort: 'H'
Erklärung: Strings sind 0-indexiert, das erste Zeichen hat Index 0. charAt(0) liefert das primitive char 'H' (mit einfachen Anführungszeichen). Achtung: charAt(5) bei einem 5-Zeichen-String wäre IndexOutOfBounds.
- F2.Was gibt "Hallo Welt".substring(0, 5) zurück?
Antwort: "Hallo"
Erklärung: substring(start, end) ist start INKLUSIV und end EXKLUSIV. Index 0,1,2,3,4 → 'Hallo'. Index 5 wäre das Leerzeichen, ist aber NICHT enthalten. Klassischer Klausur-Trick.
- F3.Welche Aussage über String-Immutability in Java/Python ist KORREKT?
Antwort: Operationen liefern neue Strings, der Original bleibt unverändert
Erklärung: Strings sind immutable, jede Operation (toUpperCase, replace, substring) liefert einen NEUEN String, der originale bleibt. Deshalb muss man oft 's = s.toUpperCase()' schreiben, sonst geht das Ergebnis verloren.
- F4.In Java: wie vergleichst du korrekt, ob zwei Strings den gleichen Inhalt haben?
Antwort: a.equals(b)
Erklärung: .equals() vergleicht den INHALT. == vergleicht die Referenz (zwei Variablen, die auf das gleiche Objekt zeigen). Wegen String-Pool kann == bei gleichen Literalen true sein, aber als Inhaltsvergleich ist es nicht verlässlich, besonders bei zur Laufzeit erzeugten Strings (z. B. via new String(...)). Klausur-Klassiker: für Inhaltsvergleich in Java immer .equals() verwenden.
- F5.Was gibt "Hallo Welt".indexOf("xyz") zurück, wenn "xyz" nicht gefunden wird?
Antwort: -1
Erklärung: indexOf liefert −1 wenn der Suchstring nicht gefunden wird. Daher der Idiom-Check 'if (s.indexOf(...) != -1)'. Auf −1 als Index zugreifen wäre dann StringIndexOutOfBounds.
- F6.Wie viele Vergleiche macht ein naives indexOf im Worst-Case bei einem Text der Länge n und einem Suchstring der Länge m?
Antwort: O(n · m)
Erklärung: Ein **naiver** Substring-Suchalgorithmus prüft an jeder der ~n Positionen, ob die nächsten m Zeichen passen, also bis zu n·m Vergleiche. Bessere Algorithmen wie KMP oder Boyer-Moore schaffen O(n+m). Die konkrete Implementierung von Java `String.indexOf` und Python `str.find` ist sprach-/versionsabhängig und kann optimiert sein; für Klausuren reicht meist die naive Analyse, wenn ausdrücklich danach gefragt wird.
- F7.Du baust einen großen String in einer Schleife auf. Was ist das Performance-Problem mit s = s + ... in Java?
Antwort: Strings sind immutable, jedes + erzeugt einen NEUEN String, Schleife wird O(n²)
Erklärung: Wegen Immutability erzeugt jedes + einen kompletten neuen String. In einer Schleife mit 1000 Iterationen: 1000 neue Strings, jeder kopiert den alten, O(n²). Lösung: StringBuilder in Java, ''.join(list) in Python.
- F8.Was ist "Hallo Welt".split(" ") in Java/Python?
Antwort: Ein String-Array/Liste: ['Hallo', 'Welt']
Erklärung: split teilt den String am Trennzeichen und liefert ein Array (Java: String[]) bzw. eine Liste (Python: list). Häufig genutzt für Tokenisierung von Eingaben. Achtung Java: `split` nimmt eine **Regex**, nicht einen wörtlichen Trenner, bei `.`, `|`, `?`, `*`, `+` escapen. Für **echtes CSV** mit Quotes/Escaping besser eine CSV-Bibliothek statt `split(",")`. Umkehr: String.join(...) bzw. ''.join(...).