// TreeSet variant allowing multiple elements which are considered
// equal by the comparator but not by eq().
// All operations O(log n) with n being the number of _different_ elements.
sclass TreeSetWithDuplicates extends AbstractSet {
NavigableSet> internal;
Comparator comparator;
int size;
*() { internal = new TreeSet; }
*(Comparator *comparator) {
internal = new TreeSet>((setA, setB) -> {
ret comparator.compare(main first(setA), main first(setB));
});
}
protected *(NavigableSet> *internal) {}
// Now using CompactLinkedHashSet
swappable Set makeInternalSet() { ret new CompactLinkedHashSet; }
public bool add(A a) {
Set newSet = addAndReturnCollection(makeInternalSet(), a);
Set found = navigableSet_find(internal, newSet);
if (found != null) {
if (!found.add(a)) false;
} else
internal.add(newSet);
++size;
true;
}
public bool remove(O a) {
Set newSet = addAndReturnCollection(makeInternalSet(), (A) a);
Set found = navigableSet_find(internal, newSet);
if (found == null) false;
if (l(found) == 1)
internal.remove(found);
else
found.remove(a);
--size;
true;
}
A first() {
ret main first(main first(internal));
}
A last() {
ret main last(main last(internal));
}
public ItIt iterator() {
ret nestedIterator(internal, methodLambda0 iterator);
}
public int size() { ret size; }
// may return null
Set tiedForFirst() { ret main first(internal); }
public bool contains(O a) {
Set newSet = addAndReturnCollection(makeInternalSet(), (A) a);
ret navigableSet_find(internal, newSet) != null;
}
}