18Was sind Generics und was ist Type Erasure?
Generics ermöglichen es dem Code, typsichere Container und APIs auszudrücken, wie z. B. List<String>. Zum Kompilierzeit überprüft der Compiler die Typen und fügt bei Bedarf Casts ein. Zur Laufzeit wird die meisten generischen Typinformation entfernt (erased), sodass List<String> und List<Integer> dieselbe Runtime-Klasse teilen. Deshalb können Sie nicht direkt new T() erstellen, primitive Typ-Parameter verwenden oder zuverlässig instanceof List<String> prüfen.
List<String> names = new ArrayList<>();
names.add("Alice");
List<? extends Number> producer;
List<? super Integer> consumer;
19Was ist das Java Collections Framework?
Das Collections Framework ist eine Reihe von Schnittstellen und Implementierungen zum Speichern und Verarbeiten von Gruppen von Objekten. Zu den Kernschnittstellen gehören List, Set, Queue, Deque und Map. Zu den Implementierungen zählen ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap und PriorityQueue. Wählen Sie eine Sammlung basierend auf dem Zugriffsmuster, den Anforderungsanforderungen an die Reihenfolge, die Einzigartigkeit, die Suchkomplexität, den Speicher-Overhead und die Konkurrenzbedürfnisse.
List<String> list = new ArrayList<>();
Set<Long> ids = new HashSet<>();
Map<Long, User> usersById = new HashMap<>();
Deque<String> queue = new ArrayDeque<>();
20Wie funktioniert HashMap?
HashMap speichert Einträge in Buckets, die durch einen Hash des Schlüssels ausgewählt werden. Für die Suche berechnet es den Hash, findet das Bucket und vergleicht Schlüssel mit equals. Kollisionen werden innerhalb des Buckets behandelt; in modernem Java können lange Ketten unter bestimmten Bedingungen in einen ausgewogenen Baum umgewandelt werden (treeified). HashMap erlaubt einen null-Schlüssel und null-Werte, ist nicht thread-sicher und kann sich vergrößern, wenn der Load Factor Schwellenwert überschritten wird.
Map<Long, User> users = new HashMap<>();
users.put(user.id(), user);
User found = users.get(user.id());
21Was ist der Unterschied zwischen HashMap, LinkedHashMap, TreeMap und ConcurrentHashMap?
HashMap bietet schnellen unsortierten Zugriff und ist nicht thread-sicher. LinkedHashMap bewahrt die Einfüge- oder Zugriffsreihenfolge und ist nützlich für LRU-ähnliche Caches. TreeMap hält Schlüssel nach natürlicher Reihenfolge oder einem Comparator sortiert und hat O(log n) Operationen. ConcurrentHashMap ist für den gleichzeitigen Zugriff mit segmentierter/interner Synchronisierung konzipiert, erlaubt keine null-Schlüssel oder -werte und ist unter Last gegenüber synchronizedMap vorzuziehen.
map.computeIfAbsent(key, ignored -> loadValue());
22Was ist der Unterschied zwischen ArrayList und LinkedList?
ArrayList basiert auf einem Array. Es bietet schnellen indexbasierten Zugriff, eine kompakte Speicheranordnung und effiziente Iteration, aber das Einfügen in die Mitte erfordert das Verschieben von Elementen. LinkedList ist eine doppelt verlinkte Liste. Sie hat ein günstigeres Einfügen, wenn der Knoten bereits bekannt ist, aber der indexbasierte Zugriff ist O(n), der Speicher-Overhead ist höher und die Cache-Lokalität ist schlechter. In vielen realen Anwendungen ist ArrayList schneller, selbst wenn einige Einfügungen beteiligt sind.
23Was ist der Unterschied zwischen Comparable und Comparator?
Comparable definiert die natürliche Reihenfolge innerhalb der Klasse über compareTo. Comparator ist ein separates Objekt oder Lambda, das eine externe Sortierung definiert. Comparable ist nützlich, wenn ein Typ eine offensichtliche Standardreihenfolge hat. Comparator ist besser geeignet, wenn es mehrere Ordnungen gibt, wie z. B. nach Name, Datum oder Priorität. compare und compareTo müssen konsistent und vorzugsweise mit equals kompatibel sein, wenn sie in sortierten Sets oder Maps verwendet werden.
class User implements Comparable<User> {
private int age;
@Override
public int compareTo(User other) {
return Integer.compare(age, other.age);
}
}
Comparator<User> byName =
Comparator.comparing(User::getName);
Comparator<User> byAgeThenName =
Comparator.comparingInt(User::getAge)
.thenComparing(User::getName);