making set act more like a hashset

This commit is contained in:
Brian Long 2020-12-07 22:10:24 -05:00
parent a40fec7b8f
commit f7505475fb

View File

@ -3,9 +3,11 @@ package me.brianlong.git;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Queue; import java.util.Queue;
import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
public class UniquePriorityFifoQueue<T> implements Queue<T> { public class UniquePriorityFifoQueue<T> implements Queue<T> {
@ -13,15 +15,20 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
private final Counter counter = new SimpleCounter(); private final Counter counter = new SimpleCounter();
private final Counter fakeCounter = new FakeCounter(); private final Counter fakeCounter = new FakeCounter();
private final TreeSet<PriorityFifoElement<T>> elements; private final TreeSet<PriorityFifoElement<T>> elements;
private final Set<PriorityFifoElement<T>> uelements;
public UniquePriorityFifoQueue() { public UniquePriorityFifoQueue() {
this.elements = new TreeSet<PriorityFifoElement<T>>(); this.elements = new TreeSet<PriorityFifoElement<T>>();
this.uelements = new HashSet<PriorityFifoElement<T>>();
} }
public UniquePriorityFifoQueue(Collection<? extends T> c) { public UniquePriorityFifoQueue(Collection<? extends T> c) {
this.elements = new TreeSet<PriorityFifoElement<T>>(); this();
for (T element : c) for (T e : c) {
this.elements.add(new PriorityFifoElement<T>(element, this.counter)); PriorityFifoElement<T> element = new PriorityFifoElement<T>(e, this.counter);
this.elements.add(element);
this.uelements.add(element);
}
} }
public UniquePriorityFifoQueue(final Comparator<? super T> comparator) { public UniquePriorityFifoQueue(final Comparator<? super T> comparator) {
@ -33,29 +40,36 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
return o1.compareTo(o2); return o1.compareTo(o2);
} }
}); });
this.uelements = new HashSet<PriorityFifoElement<T>>();
} }
@Override @Override
public boolean add(T e) { public boolean add(T e) {
return this.elements.add(new PriorityFifoElement<T>(e, this.counter)); PriorityFifoElement<T> element = new PriorityFifoElement<T>(e, this.counter);
return this.elements.add(element) && this.uelements.add(element);
} }
@Override @Override
public boolean addAll(Collection<? extends T> c) { public boolean addAll(Collection<? extends T> c) {
if (c != null) for (T e : c) if (c != null) for (T e : c) {
this.elements.add(new PriorityFifoElement<T>(e, this.counter)); PriorityFifoElement<T> element = new PriorityFifoElement<T>(e, this.counter);
this.elements.add(element);
this.uelements.add(element);
}
return true; return true;
} }
@Override @Override
public void clear() { public void clear() {
this.elements.clear(); this.elements.clear();
this.uelements.clear();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public boolean contains(Object o) { public boolean contains(Object o) {
return this.elements.contains(new PriorityFifoElement<T>((T)o, this.fakeCounter)); return this.uelements.contains(new PriorityFifoElement<T>((T)o, this.fakeCounter));
} }
@Override @Override
@ -80,6 +94,8 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
public Iterator<T> iterator() { public Iterator<T> iterator() {
final Iterator<PriorityFifoElement<T>> i = this.elements.iterator(); final Iterator<PriorityFifoElement<T>> i = this.elements.iterator();
return new Iterator<T>() { return new Iterator<T>() {
private T lastElement;
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return i.hasNext(); return i.hasNext();
@ -87,31 +103,37 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
@Override @Override
public T next() { public T next() {
return i.next().element; this.lastElement = i.next().element;
return this.lastElement;
} }
@Override @Override
public void remove() { public void remove() {
i.remove(); i.remove();
uelements.remove(this.lastElement);
} }
}; };
} }
@Override @Override
public boolean offer(T e) { public boolean offer(T e) {
return this.elements.add(new PriorityFifoElement<T>(e, this.counter)); PriorityFifoElement<T> element = new PriorityFifoElement<T>(e, this.counter);
return this.elements.add(element) && this.uelements.add(element);
} }
@Override @Override
public T peek() { public T peek() {
Iterator<T> i = this.iterator(); Iterator<PriorityFifoElement<T>> i = this.elements.iterator();
return i.hasNext() ? i.next() : null; return i.hasNext() ? i.next().element : null;
} }
@Override @Override
public T poll() { public T poll() {
PriorityFifoElement<T> element = this.elements.pollFirst(); PriorityFifoElement<T> element = this.elements.pollFirst();
return element == null ? null : element.element; if (element == null)
return null;
this.uelements.remove(element);
return element.element;
} }
@Override @Override
@ -119,13 +141,18 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
PriorityFifoElement<T> element = this.elements.pollFirst(); PriorityFifoElement<T> element = this.elements.pollFirst();
if (element == null) if (element == null)
throw new NoSuchElementException(); throw new NoSuchElementException();
this.uelements.remove(element);
return element.element; return element.element;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public boolean remove(Object o) { public boolean remove(Object o) {
return this.elements.remove(new PriorityFifoElement<T>((T)o, this.fakeCounter)); PriorityFifoElement<T> element = new PriorityFifoElement<T>((T)o, this.fakeCounter);
this.uelements.remove(element);
element = this.find(element.element);
return this.elements.remove(element);
} }
@Override @Override
@ -139,9 +166,12 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
public boolean retainAll(Collection<?> c) { public boolean retainAll(Collection<?> c) {
Iterator<PriorityFifoElement<T>> i = this.elements.iterator(); Iterator<PriorityFifoElement<T>> i = this.elements.iterator();
while (i.hasNext()) { while (i.hasNext()) {
T e = i.next().element; PriorityFifoElement<T> e = i.next();
if (!c.contains(e)) T element = e.element;
if (!c.contains(element)) {
i.remove(); i.remove();
this.uelements.remove(e);
}
} }
return true; return true;
@ -173,6 +203,15 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
return a; return a;
} }
private PriorityFifoElement<T> find(T e) {
for (PriorityFifoElement<T> element : this.elements) {
if (element.element.equals(e))
return element;
}
return null;
}
private class PriorityFifoElement<E> implements Comparable<PriorityFifoElement<E>> { private class PriorityFifoElement<E> implements Comparable<PriorityFifoElement<E>> {
@ -187,7 +226,9 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
@Override @Override
public int compareTo(PriorityFifoElement<E> o) { public int compareTo(PriorityFifoElement<E> o) {
if (o == null) return 1; if (this.fifoId < 0) return 0;
else if (o == null) return 1;
else if (o.fifoId < 0) return 0;
else return this.fifoId - o.fifoId; else return this.fifoId - o.fifoId;
} }
@ -217,7 +258,7 @@ public class UniquePriorityFifoQueue<T> implements Queue<T> {
public class FakeCounter implements Counter { public class FakeCounter implements Counter {
public int next() { public int next() {
return 0; return -1;
} }
} }