Java Fortgeschrittenen Schulung – Kursbezug
Ziel dieses Kapitels: Sie wählen List/Set/Map bewusst, reduzieren Bugs durch Typsicherheit und nutzen Wildcards (Producer/Consumer) für saubere API-Signaturen.
Worum geht’s?
- List vs. Set vs. Map: wann welches Interface?
- Praxis-Intuition: ArrayList, HashSet, HashMap (typische Fälle).
- Generics für Typsicherheit: weniger Casts, weniger Runtime-Fehler.
- Wildcards:
? extends/? super(PECS).
Lehr-/Lernziele
- (LZ1) die passende Collection (List/Set/Map) für einen Anwendungsfall begründet auswählen.
- (LZ2) Generics nutzen, um APIs typsicher zu machen (ohne unnötige Casts/Warnungen).
- (LZ3) Wildcards korrekt einsetzen (
? extends/? super) und PECS auf reale Methoden anwenden.
Welche Collection wofür?
import java.util.*;
public class Auswahl {
public static void main(String[] args) {
List<String> teilnehmer = new ArrayList<>(); // Reihenfolge wichtig, Duplikate möglich
Set<String> tags = new HashSet<>(); // eindeutig
Map<String, Integer> plaetzeProOrt = new HashMap<>(); // Lookup per Schlüssel
teilnehmer.add("Mia");
teilnehmer.add("Mia"); // Duplikat ok
tags.add("Java");
tags.add("Java"); // Duplikat wird ignoriert
plaetzeProOrt.put("Hamburg", 12);
System.out.println(teilnehmer);
System.out.println(tags);
System.out.println(plaetzeProOrt.get("Hamburg"));
}
}Generics: Typsicherheit ohne Casting
Mit Generics vermeiden Sie ClassCastExceptions und machen Absichten im Code sichtbar.
import java.util.*;
public class GenericsDemo {
public static void main(String[] args) {
List<Object> roh = new ArrayList<>();
roh.add("Java");
roh.add(123); // Mischtyp → später Ärger
List<String> sicher = new ArrayList<>();
sicher.add("Java");
// sicher.add(123); // Compiler verhindert das
}
}Map-Pattern: Zählen in der Praxis
import java.util.*;
public class Zaehlen {
public static void main(String[] args) {
List<String> buchungen = Arrays.asList("Hamburg","Berlin","Hamburg","Koeln","Berlin");
Map<String, Integer> count = new HashMap<>();
for(String ort : buchungen) {
count.merge(ort, 1, Integer::sum);
}
System.out.println(count);
}
}Wildcards: ? extends / ? super (PECS)
import java.util.*;
public class Wildcards {
// Producer: wir lesen Numbers
static double summe(List<? extends Number> nums) {
double s = 0;
for (Number n : nums) s += n.doubleValue();
return s;
}
// Consumer: wir schreiben Integers hinein
static void fuegeDefaultsHinzu(List<? super Integer> out) {
out.add(1);
out.add(2);
}
public static void main(String[] args) {
System.out.println(summe(Arrays.asList(1,2,3)));
List<Number> ziel = new ArrayList<>();
fuegeDefaultsHinzu(ziel);
System.out.println(ziel);
}
}Praxisaufgabe (Mini)
- Erstellen Sie eine
List<String>mit 6 Buchungs-Orten (z.B. Hamburg, Berlin …) – gern mit Duplikaten. - Erzeugen Sie daraus ein
Set<String>(Duplikate entfernen). - Bauen Sie eine
Map<String,Integer>, die pro Ort die Anzahl Vorkommen zählt. - Bonus: Implementieren Sie
summe(List<? extends Number>)und summieren Sie 3 Beispiel-Umsätze.
Lösung anzeigen
import java.util.*;
public class Praxis {
public static void main(String[] args) {
List<String> orte = Arrays.asList(
"Hamburg","Berlin","Hamburg","Muenchen","Koeln","Berlin"
);
// (LZ1) Set: Duplikate entfernen
Set<String> eindeutig = new HashSet<>(orte);
// (LZ1) Map: zählen
Map<String, Integer> zaehlung = new HashMap<>();
for(String ort : orte) zaehlung.merge(ort, 1, Integer::sum);
System.out.println("Eindeutige Orte: " + eindeutig);
System.out.println("Buchungen pro Ort: " + zaehlung);
// (LZ3) Producer = extends
System.out.println("Umsatz-Summe: " + summe(Arrays.asList(199.0, 299.0, 149.5)));
}
static double summe(List<? extends Number> nums) {
double s = 0;
for(Number n : nums) s += n.doubleValue();
return s;
}
}Optional: typische Stolperfallen
- Generics sind invariabel:
List<Object>ist nichtList<String>. - ? extends: gut zum Lesen – aber i.d.R. nicht sinnvoll „hinzufügen“.
- equals/hashCode: für Set/Map-Schlüssel müssen sie korrekt & stabil sein.
Kurz-Takeaways
- List = Reihenfolge/Index, Set = eindeutig, Map = Lookup.
- Generics machen APIs typsicher und reduzieren Runtime-Fehler.
- PECS: Producer
extends, Consumersuper.