/*
* This file is part of Cubic Chunks Mod, licensed under the MIT License (MIT).
*
* Copyright (c) 2015 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package cubicchunks.util;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.annotation.Nonnull;
public class ArrayDequeHashSet<E> implements Deque<E>, Set<E> {
private Set<E> set = new HashSet<>();
private Deque<E> deque = new ArrayDeque<>();
@Override
public void addFirst(E e) {
if (e == null) {
throw new NullPointerException();
}
if (set.add(e)) {
deque.addFirst(e);
} else {
deque.remove(e);
deque.addFirst(e);
}
assert set.size() == deque.size();
}
@Override
public void addLast(E e) {
if (e == null) {
throw new NullPointerException();
}
if (set.add(e)) {
deque.addLast(e);
} else {
deque.remove(e);
deque.add(e);
}
assert set.size() == deque.size();
}
@Override
public boolean offerFirst(E e) {
addFirst(e);
assert set.size() == deque.size();
return true;
}
@Override
public boolean offerLast(E e) {
addLast(e);
assert set.size() == deque.size();
return true;
}
@Override
public E removeFirst() {
E e = deque.removeFirst();
set.remove(e);
assert set.size() == deque.size();
return e;
}
@Override
public E removeLast() {
E e = deque.removeLast();
set.remove(e);
assert set.size() == deque.size();
return e;
}
@Override
public E pollFirst() {
E e = deque.pollFirst();
if (e != null) {
set.remove(e);
}
assert set.size() == deque.size();
return e;
}
@Override
public E pollLast() {
E e = deque.pollLast();
if (e != null) {
set.remove(e);
}
assert set.size() == deque.size();
return e;
}
@Override
public E getFirst() {
return deque.getFirst();
}
@Override
public E getLast() {
return deque.getLast();
}
@Override
public E peekFirst() {
return deque.peekFirst();
}
@Override
public E peekLast() {
return deque.peekLast();
}
@Override
public boolean removeFirstOccurrence(Object o) {
set.remove(o);
boolean b = deque.removeFirstOccurrence(o);
assert set.size() == deque.size();
return b;
}
@Override
public boolean removeLastOccurrence(Object o) {
//there is only one occurrence of any element
return removeFirstOccurrence(o);
}
@Override
public boolean add(E e) {
if (e == null) {
throw new NullPointerException();
}
boolean b = set.add(e) && deque.add(e);
assert set.size() == deque.size();
return b;
}
@Override
public boolean offer(E e) {
return offerLast(e);
}
@Override
public E remove() {
E removed = deque.remove();
set.remove(removed);
assert set.size() == deque.size();
return removed;
}
@Override
public E poll() {
E e = deque.poll();
if (e != null)
set.remove(e);
assert set.size() == deque.size();
return e;
}
@Override
public E element() {
return deque.element();
}
@Override
public E peek() {
return deque.peek();
}
@Override
public void push(E e) {
if (e == null) {
throw new NullPointerException();
}
if (set.add(e)) {
deque.push(e);
}
assert set.size() == deque.size();
}
@Override
public E pop() {
E e = deque.pop();
set.remove(e);
assert set.size() == deque.size();
return e;
}
@Override
public boolean remove(Object o) {
boolean b;
if (b = set.remove(o)) {
deque.remove(o);
}
assert set.size() == deque.size();
return b;
}
@Override
public boolean containsAll(@Nonnull Collection<?> c) {
return set.containsAll(c);
}
@Override
public boolean addAll(@Nonnull Collection<? extends E> c) {
for (E e : c) {
if (e == null) {
throw new NullPointerException();
}
if (!set.contains(e)) {
deque.add(e);
}
}
boolean b = set.addAll(c);
assert set.size() == deque.size();
return b;
}
@Override
public boolean removeAll(@Nonnull Collection<?> c) {
boolean b = set.removeAll(c);
boolean b2 = deque.removeAll(c);
assert b == b2;
assert set.size() == deque.size();
return b;
}
@Override
public boolean retainAll(@Nonnull Collection<?> c) {
boolean b = set.retainAll(c);
if (b) {
deque.retainAll(c);
}
assert set.size() == deque.size();
return b;
}
@Override
public void clear() {
deque.clear();
set.clear();
}
@Override
public boolean contains(Object o) {
return set.contains(o);
}
@Override
public int size() {
assert set.size() == deque.size();
return set.size();
}
@Override
public boolean isEmpty() {
assert set.isEmpty() == deque.isEmpty();
return set.isEmpty();
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
Iterator<E> dequeIt = deque.iterator();
E lastNext;
@Override
public boolean hasNext() {
return dequeIt.hasNext();
}
@Override
public E next() {
return lastNext = dequeIt.next();
}
@Override
public void remove() {
set.remove(lastNext);
dequeIt.remove();
assert set.size() == deque.size();
}
};
}
@Override
public Object[] toArray() {
return deque.toArray();
}
@Override
public <T> T[] toArray(@Nonnull T[] a) {
return deque.toArray(a);
}
@Override
public Iterator<E> descendingIterator() {
return new Iterator<E>() {
Iterator<E> dequeIt = deque.descendingIterator();
E lastNext;
@Override
public boolean hasNext() {
return dequeIt.hasNext();
}
@Override
public E next() {
return lastNext = dequeIt.next();
}
@Override
public void remove() {
set.remove(lastNext);
dequeIt.remove();
assert set.size() == deque.size();
}
};
}
}