31 private final LinkedHashMap<WeakKey<E>, Object> map =
new LinkedHashMap<>();
32 private static final Object PRESENT =
new Object();
51 requireNonNullParam(collection,
"collection",
"WeakLinkedHashSet");
56 public boolean add(E e) {
57 requireNonNullParam(e,
"e",
"WeakLinkedHashSet.add");
60 return map.putLast(
new WeakKey<>(e), PRESENT) ==
null;
64 public void addFirst(E e) {
65 requireNonNullParam(e,
"e",
"WeakLinkedHashSet.addFirst");
68 map.putFirst(
new WeakKey<>(e), PRESENT);
72 public void addLast(E e) {
73 requireNonNullParam(e,
"e",
"WeakLinkedHashSet.addLast");
76 map.putLast(
new WeakKey<>(e), PRESENT);
80 public boolean remove(Object o) {
81 requireNonNullParam(o,
"o",
"WeakLinkedHashSet.remove");
84 return map.remove(
new WeakKey<>(o)) !=
null;
88 public boolean contains(Object o) {
89 requireNonNullParam(o,
"o",
"WeakLinkedHashSet.contains");
92 return map.containsKey(
new WeakKey<>(o));
102 private void purgeCollected() {
103 map.keySet().removeIf(key -> key.get() ==
null);
107 public Iterator<E> iterator() {
109 return new WeakKeyIterator(map.keySet().iterator());
113 public SequencedSet<E> reversed() {
116 return new ReversedView<>(
this, map.sequencedKeySet().reversed());
120 public Spliterator<E> spliterator() {
121 return Spliterators.spliteratorUnknownSize(
122 iterator(), Spliterator.DISTINCT | Spliterator.ORDERED | Spliterator.NONNULL);
125 private static final class WeakKey<T>
extends WeakReference<T> {
126 private final int m_hashCode;
128 WeakKey(T referent) {
130 m_hashCode = referent.hashCode();
134 public boolean equals(Object obj) {
135 if (!(obj instanceof WeakKey<?> other)) {
140 return ref !=
null && ref.equals(other.get());
144 public int hashCode() {
149 private class WeakKeyIterator
implements Iterator<E> {
150 private final ArrayList<WeakKey<E>> keys =
new ArrayList<>();
151 private int nextIndex;
152 private E nextElement =
null;
153 private E lastReturnedElement =
null;
155 WeakKeyIterator(Iterator<WeakKey<E>> mapIterator) {
156 mapIterator.forEachRemaining(keys::add);
160 public boolean hasNext() {
161 while (nextElement ==
null && nextIndex < keys.size()) {
162 WeakKey<E> key = keys.get(nextIndex++);
163 nextElement = key.get();
164 if (nextElement ==
null) {
168 return nextElement !=
null;
174 throw new NoSuchElementException();
176 E element = nextElement;
177 lastReturnedElement = element;
183 public void remove() {
184 if (lastReturnedElement ==
null) {
185 throw new IllegalStateException();
188 map.remove(
new WeakKey<>(lastReturnedElement));
189 lastReturnedElement =
null;
193 private static class ReversedView<E>
extends AbstractSet<E> implements SequencedSet<E> {
195 private final SequencedSet<WeakKey<E>> reversedKeys;
198 this.originalSet = originalSet;
199 this.reversedKeys = reversedKeys;
204 return originalSet.size();
208 public Iterator<E> iterator() {
209 return originalSet.new WeakKeyIterator(reversedKeys.iterator());
213 public SequencedSet<E> reversed() {
218 public boolean add(E e) {
219 return originalSet.add(e);
223 public boolean remove(Object o) {
224 return originalSet.remove(o);
228 public boolean contains(Object o) {
229 return originalSet.contains(o);
233 public void addFirst(E e) {
234 originalSet.addLast(e);
238 public void addLast(E e) {
239 originalSet.addFirst(e);
243 public E getFirst() {
244 return originalSet.getLast();
249 return originalSet.getFirst();
253 public E removeFirst() {
254 return originalSet.removeLast();
258 public E removeLast() {
259 return originalSet.removeFirst();
263 public Spliterator<E> spliterator() {
264 return Spliterators.spliteratorUnknownSize(
265 iterator(), Spliterator.DISTINCT | Spliterator.ORDERED | Spliterator.NONNULL);