01 · Problem
Wofür braucht man das?
Set-Algebra wird in Anwendungscode oft mit wiederholten Schleifen und leicht verwechselter Differenzrichtung nachgebaut.
02 · Denkmodell
Das mentale Modell
Ein Set beschreibt Mitgliedschaft. Union, Intersection und Difference sollten als reine Operationen mit eindeutiger Links-rechts-Richtung lesbar sein.
BetterSet bietet filter, merge, except und both. merge mutiert; except berechnet entgegen der üblichen Erwartung other minus this und Rückgaben verlieren teils den BetterSet-Typ.
03 · Kontrollfluss
Was passiert in welcher Reihenfolge?
- Zwei Iterables als linke und rechte Menge auffassen.
- Für jede Operation die Richtung ausdrücklich festlegen.
- Mit has in linearer Zeit Mitgliedschaft prüfen.
- Ein neues Set zurückgeben, sofern Mutation nicht Teil des Namens ist.
04 · Bauteile
Die entscheidenden Verträge
merge(other)
Mutierende Vereinigung im vorhandenen Paket.
both(other)
Schnittmenge der beiden Sets.
except(other)
Berechnet aktuell other minus this statt this minus other.
filter(predicate)
Erzeugt ein BetterSet mit passenden Werten.
05 · Build it yourself
Selbst implementieren
Implementiere mathematische Operationen zunächst als pure Funktionen; mutierende Kurzformen können später bewusst ergänzt werden.
- Akzeptiere Iterable für Union und ReadonlySet für schnelle Mitgliedschaftstests.
- Definiere difference(left, right) immer als Werte aus left, die nicht in right liegen.
- Gib durchgehend denselben Collection-Typ zurück.
class SetOps<T> extends Set<T> {
union(other: Iterable<T>) {
return new SetOps([...this, ...other]);
}
intersection(other: ReadonlySet<T>) {
return new SetOps([...this].filter(value => other.has(value)));
}
difference(other: ReadonlySet<T>) {
return new SetOps([...this].filter(value => !other.has(value)));
}
}06 · Verifizieren
Was du testen solltest
- Leere, identische und disjunkte Sets liefern die mathematisch erwarteten Ergebnisse.
- difference(A, B) und difference(B, A) werden separat geprüft.
- Objekte folgen dokumentiert Referenzgleichheit und Eingaben bleiben unverändert.
07 · Grenzen
Kompromisse und Stolperfallen
- Native Set-Gleichheit ist SameValueZero, keine strukturelle Objektgleichheit.
- Immutable Ergebnisse benötigen zusätzliche Allokationen, sind aber leichter zu komponieren.
Eine Differenz ohne sichtbare Richtung ist eine klassische Fehlerquelle. Nutze Beispiele mit A und B in der Dokumentation und in Tests.
08 · Weiterdenken