-2
\$\begingroup\$

Implementation of java.util.Deque interface based on string of POJOs, that is plain old java object, encapsulating a field for holding reference to each object added to deque together with append, prepend and remove methods modeling corresponding behaviours, traversed by various strategies each running behaviour required by the methods the java.util.Deque interface defines.

import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class StringDeque<E> implements Deque<E> {
 private static class Bind {
 private final Object element;
 private Bind fore;
 private Bind next;
 public Bind(Object e, Bind other) {
 element = e;
 next = other;
 }
 public Bind(Bind other, Object e) {
 element = e;
 fore = other;
 }
 public void append(Object e) { this.next = new Bind(this, e); }
 public Bind prepend(Object e) {
 Bind bind = new Bind(e, this);
 this.fore = bind;
 return bind;
 }
 public boolean remove() {
 boolean removed = false;
 if (fore != null) {
 fore.next = next;
 removed = true;
 }
 if (next != null) {
 next.fore = fore;
 removed = true;
 }
 if (removed) {
 next = null;
 fore = null;
 }
 return removed;
 }
 public static Bind fore(Object e, Bind next) {
 return new Bind(e, next);
 }
 public static Bind of(Object e) {
 return new Bind(e, null);
 }
 }
 private interface Strategy{ boolean element(Object element); }
 private static class Peakless implements Strategy {
 private Of of;
 public Peakless(Of context) { of = context; }
 @Override
 public boolean element(Object removed) {
 if (!removed.equals(of.bindings.element)) { return false; }
 if (removed.equals(of.bindings.element)) {
 of.peakless();
 return true;
 }
 return false;
 }
 }
 private static class NullPeakless implements Strategy {
 private Of of;
 public NullPeakless(Of context) { of = context; }
 @Override
 public boolean element(Object removed) {
 if (of.bindings.element != null) { return false; }
 if (of.bindings.element == null) {
 of.peakless();
 return true;
 }
 return false;
 }
 }
 private static class AllPeakless implements Strategy {
 private Of of;
 public AllPeakless(Of context) { of = context; }
 @Override
 public boolean element(Object removed) {
 if (!removed.equals(of.bindings.element)) { return false; }
 boolean result = removed.equals(of.bindings.element);
 while (!of.isEmpty() && removed.equals(of.bindings.element)) {
 of.peakless();
 }
 return result;
 }
 }
 private static class AllNullPeakless implements Strategy {
 private Of of;
 public AllNullPeakless(Of context) { of = context; }
 @Override
 public boolean element(Object removed) {
 if (of.bindings.element != null) { return false; }
 boolean result = of.bindings.element == null;
 while (of.bindings.element == null) { of.peakless(); }
 return result;
 }
 }
 private static class Nullless implements Strategy {
 private Of of;
 public Nullless(Of context) { of = context; }
 @Override
 public boolean element(Object removed) {
 boolean result = false;
 Bind bind = of.bindings;
 while (!result && bind != null) {
 if (bind.element == null) {
 bind = Of.remove(bind, bind.next);
 result = true;
 } else {
 bind = bind.next;
 }
 }
 return result;
 }
 }
 private static class Remove implements Strategy {
 private Of of;
 public Remove(Of context) { of = context; }
 @Override
 public boolean element(Object removed) {
 boolean result = false;
 Bind bind = of.bindings;
 while (!result && bind != null) {
 if (removed.equals(bind.element)) { result = bind.remove(); }
 bind = bind.next;
 }
 return result;
 }
 }
 private static class Allless implements Strategy {
 private Of of;
 public Allless(Of context) { of = context; }
 @Override
 public boolean element(Object removed) {
 boolean result = false;
 Bind bind = of.bindings;
 while (bind != null) {
 if (removed.equals(bind.element)) {
 bind = of.remove(bind, bind.next);
 result = true;
 } else {
 bind = bind.next;
 }
 }
 return result;
 }
 }
 private static class AllNullless implements Strategy {
 private Of of;
 public AllNullless(Of context) { of = context; }
 @Override
 public boolean element(Object removed) {
 boolean result = false;
 Bind bind = of.bindings;
 while (bind != null) {
 if (bind.element == null) {
 bind = of.remove(bind, bind.next);
 } else {
 bind = bind.next;
 }
 }
 return result;
 }
 }
 private static class LastNullRemove implements Strategy {
 private Of of;
 public LastNullRemove(Of context) { of = context; }
 @Override
 public boolean element(Object element) {
 Bind edge = of.edge();
 if (of.bindings == edge && element == edge.element) {
 of.clear();
 return true;
 }
 boolean result = false;
 Bind bind = edge;
 while (bind != null && bind.element != null) { bind = bind.fore; }
 if (bind.element == null) { result = bind.remove(); }
 return result;
 }
 }
 private static class LastRemove implements Strategy {
 private Of of;
 public LastRemove(Of context) { of = context; }
 @Override
 public boolean element(Object element) {
 Bind edge = of.edge();
 if (of.bindings == edge && element.equals(edge.element)) {
 of.clear();
 return true;
 }
 boolean result = false;
 Bind bind = edge;
 while (bind != null && !element.equals(bind.element)) {
 bind = bind.fore;
 }
 if (element.equals(bind.element)) { result = bind.remove(); }
 return result;
 }
 }
 private static class Append implements Strategy {
 private Of of;
 public Append(Of context) { of = context; }
 public Of context() { return of; }
 @Override
 public boolean element(Object element) {
 if (of.bindings == null) {
 of.bindings = Bind.fore(element, null);
 return true;
 }
 of.edge().append(element);
 return true;
 }
 }
 private static class AppendBounded extends Append {
 private int bound;
 public AppendBounded(Of context, int bound) {
 super(context);
 this.bound = bound;
 }
 @Override
 public boolean element(Object element) {
 if ( super.context().size() == bound) { return false; }
 return super.element(element);
 }
 }
 private static class Prepend implements Strategy {
 private Of of;
 public Prepend(Of context) { of = context; }
 public Of context() { return of; }
 @Override
 public boolean element(Object element) {
 if (of.isEmpty()) {
 of.bindings = Bind.of(element);
 } else {
 of.bindings = of.bindings.prepend(element);
 }
 return true;
 }
 }
 private static class PrependBounded extends Prepend {
 private int bound;
 public PrependBounded(Of context, int bound) {
 super(context);
 this.bound = bound;
 }
 @Override
 public boolean element(Object element) {
 if (super.context().size() == bound) { return false; }
 return super.element(element);
 }
 }
 private static class Contains implements Strategy {
 private Of of;
 public Contains(Of context) { of = context; }
 @Override
 public boolean element(Object element) {
 if (of.isEmpty()) { return false; }
 boolean result = false;
 Bind bind = of.bindings;
 while (!result && bind != null) {
 result = element.equals(bind.element);
 bind = bind.next;
 }
 return result;
 }
 }
 private static class ContainsNull implements Strategy {
 private Of of;
 public ContainsNull(Of context) { of = context; }
 @Override
 public boolean element(Object element) {
 if (of.isEmpty()) { return false; }
 boolean result = false;
 Bind bind = of.bindings;
 while (!result && bind != null) {
 result = bind.element == null;
 bind = bind.next;
 }
 return result;
 }
 }
 private static class StrategiesFactory {
 public static Strategies with(Of of) { return new Strategies(of); }
 public static Strategies with(Of of, int bound) {
 return new BoundedStrategies(of, bound);
 }
 }
 private static class Strategies {
 private Strategy prepend, append,containsNull, contains, peakless
 , nullPeakless, nullless, remove, allNullPeakless
 , allPeakless,lastRemove, lastNullRemove, allless
 , allNullless;
 public Strategies(Of of) {
 prepend = new Prepend(of);
 append = new Append(of);
 peakless = new Peakless(of);
 nullPeakless = new NullPeakless(of);
 nullless = new Nullless(of);
 remove = new Remove(of);
 allless = new Allless(of);
 allNullless = new AllNullless(of);
 allNullPeakless = new AllNullPeakless(of);
 allPeakless = new AllPeakless(of);
 lastRemove = new LastRemove(of);
 lastNullRemove = new LastNullRemove(of);
 containsNull = new ContainsNull(of);
 contains = new Contains(of);
 }
 public Strategy append() { return append; }
 public Strategy prepend() { return prepend; }
 public Strategy peakless(Object removed) {
 return removed == null ? nullPeakless : peakless;
 }
 public Strategy remove(Object removed) {
 return removed == null ? nullless : remove;
 }
 public Strategy allPeakless(Object removed) {
 return removed == null ? allNullPeakless : allPeakless;
 }
 public Strategy allless(Object removed) {
 return removed == null ? allNullless : allless;
 }
 public Strategy lastRemove(Object removed) {
 return removed == null ? lastNullRemove : lastRemove;
 }
 public Strategy contains(Object contained) {
 return contained == null ? containsNull : contains;
 }
 }
 private static class BoundedStrategies extends Strategies {
 private Strategy prepend, append;
 public BoundedStrategies(Of of, int bound) {
 super(of);
 prepend = new PrependBounded(of, bound);
 append = new AppendBounded(of, bound);
 }
 public Strategy append() { return append; }
 public Strategy prepend() { return prepend; }
 }
 private static class Of {
 public static Bind remove(Bind removed, Bind next) {
 removed.remove();
 return next;
 }
 private Bind bindings;
 public boolean isEmpty() { return bindings == null; }
 public void peakless() { bindings = remove(bindings, bindings.next); }
 public void clear() { bindings = null; }
 public int size() {
 if (bindings == null) { return 0; }
 int abacus = 0;
 Bind bind = bindings;
 while (bind != null) {
 abacus++;
 bind = bind.next;
 }
 return abacus;
 }
 public Bind edge() {
 Bind bind = bindings;
 while (bind.next != null) { bind = bind.next; }
 return bind;
 }
 }
 private static class Ascending<F> implements java.util.Iterator<F> {
 interface Step { Bind on(); }
 private static class First implements Step {
 private Ascending context;
 private First(Ascending ascending) { context = ascending; }
 @Override
 public Bind on() {
 context.stepIndex++;
 context.removerIndex++;
 return context.of.bindings;
 }
 }
 private static class Second implements Step {
 private Ascending context;
 private Second(Ascending ascending) { context = ascending; }
 @Override
 public Bind on() {
 context.stepIndex++;
 context.removerIndex++;
 if (context.actual == null) {
 return context.previous.next;
 } else {
 context.previous = context.actual;
 return context.actual.next;
 }
 }
 }
 private static class Third implements Step {
 private Ascending context;
 public Third(Ascending context) { this.context = context; }
 @Override
 public Bind on() {
 if (context.actual == null) {
 return context.previous.next;
 } else {
 context.previous = context.actual;
 return context.actual.next;
 }
 }
 }
 public static class NoopRemover implements Runnable {
 @Override
 public void run() {}
 }
 private static class RemoveFirst implements Runnable {
 private Ascending context;
 public RemoveFirst(Ascending iterator) { context = iterator; }
 @Override
 public void run() {
 if (context.of.isEmpty()) { return; }
 context.of.peakless();
 context.stepIndex--;
 context.removerIndex--;
 }
 }
 private static class Remover implements Runnable {
 private Ascending context;
 public Remover(Ascending iterator) { context = iterator; }
 @Override
 public void run() {
 if (context.previous.next != context.actual) { return; }
 context.actual.remove();
 context.actual = null;
 }
 }
 private Of of;
 private Bind previous, actual;
 private int stepIndex = 0, removerIndex = 0;
 private Step[] returners;
 private Runnable[] removers;
 private boolean hasNext;
 public Ascending(Of context) {
 of = context;
 hasNext = !of.isEmpty();
 returners = steps(new First(this)
 , new Second(this)
 , new Third(this));
 removers = runnables(new NoopRemover()
 , new RemoveFirst(this)
 , new Remover(this));
 }
 private Step[] steps(Step ... steps) { return steps; }
 private Runnable[] runnables(Runnable ... runees) { return runees; }
 @Override
 public boolean hasNext() { return hasNext; }
 @Override
 public F next() {
 if (!hasNext()) { throw new NoSuchElementException(); }
 actual = returners[stepIndex].on();
 hasNext = actual.next != null;
 return (F) actual.element;
 }
 @Override
 public void remove() {
 if (actual == null) { return; }
 removers[removerIndex].run();
 }
 }
 private static class Descending<F> implements java.util.Iterator<F> {
 private Of of;
 private boolean hasNext;
 private Bind actual, previous;
 public Descending(Of context) {
 of = context;
 hasNext = !of.isEmpty();
 }
 @Override
 public boolean hasNext() { return hasNext; }
 @Override
 public F next() {
 if (!hasNext()) { throw new NoSuchElementException(); }
 if (actual == null) {
 actual = (previous == null) ? of.edge()
 : previous.fore;
 } else {
 actual = glide(actual, actual.fore);
 }
 hasNext = actual != of.bindings;
 return (F) actual.element;
 }
 private Bind glide(Bind former, Bind next) {
 previous = former;
 return next;
 }
 public void remove() {
 if (actual == null) { return; }
 if (actual == of.bindings) {
 of.peakless();
 } else {
 actual.remove();
 }
 actual = null;
 }
 }
 private Of of;
 private Strategies strategies;
 public StringDeque() {
 of = new Of();
 strategies = StrategiesFactory.with(of);
 }
 public StringDeque(int capacity) {
 of = new Of();
 strategies = StrategiesFactory.with(of, capacity);
 }
 @Override
 public boolean isEmpty() { return of.isEmpty(); }
 @Override
 public Object[] toArray() {
 Object[] objects = new Object[size()];
 Bind bind = of.bindings;
 int i = 0;
 while (bind != null) { bind = set(i++, bind, objects); }
 return objects;
 }
 private Bind set(int index, Bind actual, Object[] objects) {
 objects[index] = actual.element;
 return actual.next;
 }
 @Override
 public <T> T[] toArray(T[] a) {
 Bind bind = of.bindings;
 int size = size();
 int length = a.length < size ? a.length : size;
 for (int i = 0; i < length; i++) {
 a[i] = (T) bind.element;
 bind = bind.next;
 }
 return a;
 }
 @Override
 public boolean containsAll(Collection<?> c) {
 if (isEmpty()) { return c.isEmpty(); }
 boolean result = false;
 for (Iterator<?> i = c.iterator(); !result && i.hasNext();) {
 result = contains(i.next());
 }
 return result;
 }
 @Override
 public boolean removeAll(Collection<?> c) {
 if (isEmpty() || c.isEmpty()) { return false; }
 boolean result = false;
 for (Object r : c) {
 result = strategies.allPeakless(r).element(r) || result;
 if (isEmpty()) { break; }
 result = strategies.allless(r).element(r) || result;
 }
 return result;
 }
 @Override
 public boolean retainAll(Collection<?> c) {
 if (c.isEmpty() || isEmpty()) { return false; }
 boolean result = false;
 Object[] elements = toArray();
 Bind peak = null;
 for (Object contained : c) {
 for (int i = elements.length - 1; i > -1; i--) {
 if ((contained == null && elements[i] == null)
 || contained != null && contained.equals(elements[i])) {
 peak = peak == null ? Bind.of(elements[i])
 : peak.prepend(elements[i]);
 result = true;
 }
 }
 }
 if (result) {
 of.bindings = peak;
 return true;
 } else {
 return false;
 }
 }
 @Override
 public void clear() { of.clear(); }
 @Override
 public void addFirst(E e) {
 if (!strategies.prepend().element(e)) {
 throw new IllegalStateException();
 }
 }
 @Override
 public void addLast(E e) {
 if (!strategies.append().element(e)) {
 throw new IllegalStateException();
 }
 }
 @Override
 public boolean offerFirst(E e) { return strategies.prepend().element(e); }
 @Override
 public boolean offerLast(E e) { return strategies.append().element(e); }
 @Override
 public E removeFirst() {
 if (isEmpty()) { throw new NoSuchElementException(); }
 return (E) peak(of.bindings, of.bindings.next).element;
 }
 private Bind peak(Bind removed, Bind next) {
 of.bindings = next;
 removed.remove();
 return removed;
 }
 @Override
 public E removeLast() {
 if (isEmpty()) { throw new NoSuchElementException(); }
 Bind edge = of.edge();
 if (edge == of.bindings) {
 clear();
 } else {
 edge.remove();
 }
 return (E) edge.element;
 }
 @Override
 public E pollFirst() {
 if (isEmpty()) { return null; }
 return (E) peak(of.bindings, of.bindings.next).element;
 }
 @Override
 public E pollLast() {
 if (isEmpty()) { return null; }
 Bind edge = of.edge();
 if (edge == of.bindings) {
 clear();
 } else {
 edge.remove();
 }
 return (E) edge.element;
 }
 @Override
 public E getFirst() {
 if (isEmpty()) { throw new NoSuchElementException(); }
 return (E) of.bindings.element;
 }
 @Override
 public E getLast() {
 if (isEmpty()) { throw new NoSuchElementException(); }
 return (E) of.edge().element;
 }
 @Override
 public E peekFirst() {
 if (isEmpty()) { return null; }
 return (E) of.bindings.element;
 }
 @Override
 public E peekLast() {
 if (isEmpty()) { return null; }
 return (E) of.edge().element;
 }
 @Override
 public boolean removeFirstOccurrence(Object o) {
 return !isEmpty() && strategies.peakless(o).element(o)
 || !isEmpty() && strategies.remove(o).element(o);
 }
 @Override
 public boolean removeLastOccurrence(Object o) {
 return !isEmpty() && strategies.lastRemove(o).element(o);
 }
 @Override
 public boolean add(E e) {
 addLast(e);
 return true;
 }
 @Override
 public boolean offer(E e) { return offerLast(e); }
 @Override
 public E remove() { return removeFirst(); }
 @Override
 public E poll() { return pollFirst(); }
 @Override
 public E element() { return getFirst(); }
 @Override
 public E peek() { return peekFirst(); }
 @Override
 public boolean addAll(Collection<? extends E> c) {
 if (c.isEmpty()) { return false; }
 for (E element : c) {
 addLast(element);
 }
 return true;
 }
 @Override
 public void push(E e) { addFirst(e); }
 @Override
 public E pop() { return removeFirst(); }
 @Override
 public boolean remove(Object o) { return removeFirstOccurrence(o); }
 @Override
 public boolean contains(Object o) {
 return strategies.contains(o).element(o);
 }
 @Override
 public int size() { return of.size(); }
 @Override
 public Iterator<E> iterator() { return new Ascending<E>(of); }
 @Override
 public Iterator<E> descendingIterator() { return new Descending<E>(of); }
}

Usage showcase, to be ignored for review...

import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
public class StringDequeTest {
 public static void main(String[] args) {
 StringDequeTest test = new StringDequeTest(Explorers.bulk());
 test.toArrayUnderDimesioned();
 test.overall();
 }
 private static class Explorers {
 public static Granular granular() { return new Granular(); }
 public static Bulk bulk() { return new Bulk(); }
 public static TimedBulk timedBulk() { return new TimedBulk(); }
 }
 private interface Runner { void summary(boolean result); }
 private static class Plain implements Runner {
 private String text;
 public Plain(String explored) { text = explored; }
 @Override
 public void summary(boolean result) {
 if (result) {
 System.out.println(text + " ... Passed");
 } else {
 System.err.println(text + " ... Failed");
 }
 }
 }
 private interface Explorer {
 void of(String text);
 void summary(boolean result);
 void overall();
 void overall(boolean result);
 }
 private static abstract class AbstractExplorer<R extends Runner> 
 implements Explorer {
 private boolean passed = true;
 private Runner[] runners = {};
 private Runner ran(boolean result) {
 passed = passed && result;
 return ran();
 }
 private Runner ran() {
 if (runners.length == 0) { return null; }
 Runner[] runees = new Runner[runners.length - 1];
 for (int i = 0; i < runees.length; i++) {
 runees[i] = runners[i + 1];
 }
 return ran(runners[0], runees);
 }
 private Runner ran(Runner returnee, Runner[] runees) {
 runners = runees;
 return returnee;
 }
 public void run(Runner runner) { runners = append(runner, runners); }
 private Runner[] append(Runner runner, Runner ... runners) {
 Runner[] runees = new Runner[runners.length + 1];
 runees[runees.length - 1] = runner;
 for (int i = 0; i < runees.length - 1; i++) {
 runees[i] = runners[i];
 }
 return runees;
 }
 @Override
 public void summary(boolean result) { ran(result).summary(result); }
 @Override
 public void overall() { overall(passed); }
 @Override
 public void overall(boolean result) {
 if (result) {
 System.out.println();
 System.out.println("Pass.");
 } else {
 System.err.println();
 System.err.println("Fail.");
 }
 }
 }
 private static class Granular extends AbstractExplorer<Plain> {
 public void of(String text) { super.run(new Plain(text)); }
 }
 private static class TimedState implements Runner {
 private String text;
 private long start, elapsed;
 public TimedState(String explored) {
 text = explored;
 start = System.nanoTime();
 }
 @Override
 public void summary(boolean result) {
 elapsed = (System.nanoTime() - start) / 1000;
 }
 public void print(boolean result) {
 String string = result ? "Passed" : "Failed";
 String message = text + " ... " + string
 + " [elapsed: " + elapsed + " ms]";
 if (result) {
 System.out.println(message);
 } else {
 System.err.println(result);
 }
 }
 }
 private static class Bulk implements Explorer {
 private Plain[] runners = {};
 private boolean[] results = {};
 public void of(String text) { run(new Plain(text)); }
 public void run(Plain runner) { runners = append(runner, runners); }
 private Plain[] append(Plain runner, Plain ... runners) {
 Plain[] runees = new Plain[runners.length + 1];
 runees[runees.length - 1] = runner;
 for (int i = 0; i < runees.length - 1; i++) {
 runees[i] = runners[i];
 }
 return runees;
 }
 @Override
 public void summary(boolean result) {
 boolean[] booleans = new boolean[results.length + 1];
 booleans[booleans.length - 1] = result;
 for (int i = 0; i < results.length; i++) {
 booleans[i] = results[i];
 }
 results = booleans;
 }
 @Override
 public void overall() {
 if (results.length == 0) { return; }
 int index = results.length - 1;
 boolean passed = results[index];
 runners[index].summary(passed);
 for (int i = index; i > -1; i--) {
 passed = passed && results[i];
 runners[i].summary(results[i]);
 }
 overall(passed);
 }
 @Override
 public void overall(boolean result) {
 if (result) {
 System.out.println();
 System.out.println("Pass.");
 } else {
 System.err.println();
 System.err.println("Fail.");
 }
 }
 }
 private static class TimedBulk implements Explorer {
 private TimedState[] runners = {};
 private boolean[] results = {};
 public void of(String text) { run(new TimedState(text)); }
 public void run(TimedState runee) { runners = append(runee, runners); }
 private TimedState[] append(TimedState runner, TimedState ... runners) {
 TimedState[] runees = new TimedState[runners.length + 1];
 runees[runees.length - 1] = runner;
 for (int i = 0; i < runees.length - 1; i++) {
 runees[i] = runners[i];
 }
 return runees;
 }
 @Override
 public void summary(boolean result) {
 boolean[] booleans = new boolean[results.length + 1];
 booleans[booleans.length - 1] = result;
 for (int i = 0; i < results.length; i++) {
 booleans[i] = results[i];
 runners[i].summary(result);
 }
 results = booleans;
 }
 @Override
 public void overall() {
 if (results.length == 0) { return; }
 int index = results.length - 1;
 boolean passed = results[index];
 runners[index].summary(passed);
 for (int i = index; i > -1; i--) {
 passed = passed && results[i];
 runners[i].print(results[i]);
 }
 overall(passed);
 }
 @Override
 public void overall(boolean result) {
 if (result) {
 System.out.println();
 System.out.println("Pass.");
 } else {
 System.err.println();
 System.err.println("Fail.");
 }
 }
 }
 private Explorer explorer;
 public StringDequeTest() { this.explorer = new Granular(); }
 public StringDequeTest(Explorer explorer) { this.explorer = explorer; }
 public void toArray() {
 int length = 5;
 Deque<Integer> deque = deque(length);
 Integer[] array = deque.toArray(new Integer[length]);
 explorer.of("toArray");
 boolean result = toString(array).equals(stringed(length));
 explorer.summary(result);
 }
 public void toArrayUnderDimesioned() {
 int length = 26, size = length/2;
 Deque<Integer> deque = deque(length);
 Integer[] array = deque.toArray(new Integer[size]);
 explorer.of("toArrayUnderDimesioned");
 boolean result = toString(array).equals(stringed(size));
 explorer.summary(result);
 }
 public void toObjectArray() {
 int length = 3;
 Deque<Integer> deque = deque(length);
 Object[] array = deque.toArray();
 explorer.of("toObjectArray");
 boolean result = toString(array).equals(stringed(length));
 explorer.summary(result);
 }
 public void clear() {
 int length = 3;
 Deque<Integer> deque = deque(length);
 explorer.of("clear");
 boolean result = deque.size() == length;
 deque.clear();
 result = result && deque.size() == 0;
 explorer.summary(result);
 }
 public void containsAll() {
 Deque<Integer> deque = deque(7);
 Integer[] contained = { 0, 1, 5 };
 explorer.of("containsAll");
 boolean result = deque.containsAll(toList(contained));
 deque = deque(0);
 result = result && !deque.containsAll(toList(contained));
 explorer.summary(result);
 }
 public void emptyDequeContainsAllEmpty() {
 Deque<Integer> deque = deque(0);
 Integer[] contained = {};
 explorer.of("emptyDequeContainsAllEmpty");
 boolean result = deque.containsAll(toList(contained));
 explorer.summary(result);
 }
 public void notContainsAll() {
 Deque<Integer> deque = new StringDeque<>();
 Integer[] contained = { 1, 5 };
 explorer.of("notContainsAll");
 boolean result = deque.containsAll(toList(contained));
 explorer.summary(result == false);
 }
 public void removeAll() {
 int length = 8;
 Deque<Integer> deque = deque(length);
 for (Iterator<Integer> i = deque.iterator(); i.hasNext();) {
 deque.addFirst(i.next());
 }
 deque.addFirst(null);
 deque.addFirst(12);
 deque.addFirst(20);
 deque.addFirst(31);
 deque.addFirst(26);
 deque.addFirst(null);
 explorer.of("removeAll");
 boolean result = deque.size() == length * 2 + 6
 && deque.removeAll(toList(null, 0, 5, 6, 12))
 && deque.size() == ((length * 2 + 6) - 9);
 explorer.summary(result);
 }
 public void removeAllUntilEmpty() {
 int length = 2;
 Deque<Integer> deque = deque(length);
 deque.addFirst(null);
 deque.addFirst(2);
 deque.addFirst(null);
 explorer.of("removeAllUntilEmpty");
 boolean result = deque.size() == length + 3
 && deque.removeAll(toList(null, 0, 1, 2, 3, 12))
 && deque.size() == 0;
 explorer.summary(result);
 }
 public void removeAllFromEmpty() {
 Deque<Integer> deque = new StringDeque<>();
 explorer.of("removeAllFromEmpty");
 boolean result = deque.removeAll(toListFrom(0, 2, 5));
 explorer.summary(result == false);
 }
 public void addFirst() {
 Deque<Integer> deque = deque(0);
 int length = 6;
 Integer[] array = new Integer[length];
 for (int i = length - 1; i > - 1; i--) { array[length - 1 - i] = i; }
 String intended = toString(array);
 explorer.of("addFirst");
 for (int i = 0; i < length; i++) { deque.addFirst(i); }
 boolean result = deque.size() == length
 && intended.equals(toString(deque.toArray()));
 explorer.summary(result);
 }
 public void addFirstToBounded() {
 String prefix = "addFirstToBounded";
 int size = 3;
 Deque<Integer> deque = deque(size, 5);
 explorer.of(prefix);
 boolean result = false;
 deque.addFirst(1);
 result = deque.size() == size + 1;
 deque.addFirst(2);
 result = result && deque.size() == size + 2;
 try {
 deque.addFirst(3);
 result = false;
 } catch(IllegalStateException e) {
 System.err.println(prefix + ": overflow due to capacity bound");
 result = result && true;
 }
 explorer.summary(result);
 }
 public void push() {
 Deque<Integer> deque = deque(0);
 int length = 6;
 Integer[] array = new Integer[length];
 for (int i = length - 1; i > - 1; i--) { array[length - 1 - i] = i; }
 String intended = toString(array);
 explorer.of("push");
 for ( int i = 0; i < length; i++ ) { deque.push(i); }
 boolean result = deque.size() == length
 && intended.equals(toString(deque.toArray()));
 explorer.summary(result);
 }
 public void pushToBounded() {
 String prefix = "pushToBounded";
 int size = 3;
 Deque<Integer> deque = deque(size, 5);
 explorer.of(prefix);
 boolean result = false;
 deque.push(1);
 result = deque.size() == size + 1;
 deque.push(2);
 result = result && deque.size() == size + 2;
 try {
 deque.push(3);
 result = false;
 } catch(IllegalStateException e) {
 System.err.println(prefix + ": overflow due to capacity bound");
 result = result && true;
 }
 explorer.summary(result);
 }
 public void addLast() {
 Deque<Integer> deque = deque(1);
 int length = 6, start = 1, end = length;
 Integer[] array = new Integer[length];
 for ( int i = 0; i < length - start; i++ ) { array[i] = i; }
 explorer.of("addLast");
 for ( int i = start; i < end; i++ ) { deque.addLast(i); array[i] = i; }
 String intended = toString(array);
 boolean result = deque.size() == length
 && intended.equals(toString(deque.toArray()));
 explorer.summary(result);
 }
 public void addLastToEmpty() {
 Deque<Integer> deque = new StringDeque<>();
 explorer.of("addLastToEmpty");
 boolean result = deque.size() == 0;
 deque.addLast(1);
 result = result && deque.size() == 1;
 explorer.summary(result);
 }
 public void addLastToBounded() {
 String prefix = "addLastToBounded";
 int size = 3;
 Deque<Integer> deque = deque(size, 5);
 explorer.of(prefix);
 boolean result = false;
 deque.addLast(1);
 result = deque.size() == size + 1;
 deque.addLast(2);
 result = result && deque.size() == size + 2;
 try {
 deque.addLast(3);
 result = false;
 } catch(IllegalStateException e) {
 System.err.println(prefix + ": overflow due to capacity bound");
 result = result && true;
 }
 explorer.summary(result);
 }
 public void addAll() {
 Deque<Integer> deque = deque(1);
 List<Integer> integers = toListFrom(1, 2, 3, 4, 5, 6);
 explorer.of("addAll");
 boolean result = deque.addAll(integers)
 && deque.size() == integers.size() + 1;
 explorer.summary(result);
 }
 public void addAllToEmpty() {
 Deque<Integer> deque = deque(0);
 List<Integer> integers = toListFrom(1, 2, 3, 4, 5, 6);
 explorer.of("addAllToEmpty");
 boolean result = deque.addAll(integers)
 && deque.size() == integers.size();
 explorer.summary(result);
 }
 public void addAllToBounded() {
 int size = 2, capacity = 5;
 Deque<Integer> deque = deque(size, capacity);
 List<Integer> integers = toListFrom(1, 2, 3, 4, 5, 6);
 explorer.of("addAllToBounded");
 boolean result = deque.size() == 2;
 try {
 deque.addAll(integers);
 result = false;
 } catch(IllegalStateException e) {
 result = result && deque.size() == capacity;
 }
 explorer.summary(result);
 }
 public void add() {
 Deque<Integer> deque = deque(1);
 int length = 6, start = 1, end = length;
 Integer[] array = new Integer[length];
 for ( int i = 0; i < length - start; i++ ) { array[i] = i; }
 explorer.of("add");
 for ( int i = start; i < end; i++ ) {
 deque.addLast(i);
 array[i] = i;
 }
 String intended = toString(array);
 boolean result = deque.size() == length
 && intended.equals(toString(deque.toArray()));
 explorer.summary(result);
 }
 public void addToEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("addToEmpty");
 boolean result = deque.size() == 0;
 deque.add(1);
 result = result && deque.size() == 1;
 explorer.summary(result);
 }
 public void addToBounded() {
 String prefix = "addToBounded";
 int size = 3;
 Deque<Integer> deque = deque(size, 5);
 explorer.of(prefix);
 boolean result = false;
 deque.addLast(1);
 result = deque.size() == size + 1;
 deque.addLast(2);
 result = result && deque.size() == size + 2;
 try {
 deque.add(3);
 result = false;
 } catch(IllegalStateException e) {
 System.err.println(prefix + ": overflow due to capacity bound");
 result = result && true;
 }
 explorer.summary(result);
 }
 public void offerFirst() {
 Deque<Integer> deque = deque(0);
 explorer.of("offerFirst");
 boolean result = deque.offerFirst(2) && deque.size() == 1;
 explorer.summary(result);
 }
 public void offerFirstToBounded() {
 Deque<Integer> deque = deque(0, 1);
 explorer.of("offerFirstToBounded");
 boolean result = deque.offerFirst(1) && deque.size() == 1
 && !deque.offerFirst(2)
 && deque.size() == 1;
 explorer.summary(result);
 }
 public void offerLast() {
 Deque<Integer> deque = deque(0);
 explorer.of("offerLast");
 boolean result = deque.offerLast(2) && deque.size() == 1;
 explorer.summary(result);
 }
 public void offerLastToBounded() {
 Deque<Integer> deque = deque(0, 1);
 explorer.of("offerLastToBounded");
 boolean result = deque.offerLast(1) && deque.size() == 1
 && !deque.offerLast(2)
 && deque.size() == 1;
 explorer.summary(result);
 }
 public void offer() {
 Deque<Integer> deque = deque(0);
 explorer.of("offer");
 boolean result = deque.offer(2) && deque.size() == 1;
 explorer.summary(result);
 }
 public void offerToBounded() {
 Deque<Integer> deque = deque(0, 1);
 explorer.of("offerToBounded");
 boolean result = deque.offer(1) && deque.size() == 1
 && !deque.offer(2)
 && deque.size() == 1;
 
 explorer.summary(result);
 }
 public void pop() {
 int length = 3;
 Deque<Integer> deque = deque(length);
 explorer.of("pop");
 boolean result = 0 == deque.pop() && deque.size() == length - 1;
 explorer.summary(result);
 }
 public void popFromEmpty() {
 String prefix = "popFromEmpty";
 Deque<Integer> deque = deque(0);
 explorer.of(prefix);
 boolean result = true;
 try {
 deque.pop();
 result = false;
 } catch(NoSuchElementException e) {
 System.err.println(prefix + ": deque is empty");
 }
 explorer.summary(result);
 }
 public void removeFirst() {
 int length = 3;
 Deque<Integer> deque = deque(length);
 explorer.of("removeFirst");
 boolean result = 0 == deque.removeFirst() && deque.size() == length - 1;
 explorer.summary(result);
 }
 public void removeFirstFromEmpty() {
 String prefix = "removeFirstFromEmpty";
 Deque<Integer> deque = new StringDeque<>();
 explorer.of(prefix);
 boolean result = true;
 try {
 deque.removeFirst();
 result = false;
 } catch(NoSuchElementException e) {
 System.err.println(prefix + ": deque is empty");
 }
 explorer.summary(result);
 }
 public void remove() {
 int length = 3;
 Deque<Integer> deque = deque(length);
 explorer.of("remove");
 boolean result = 0 == deque.remove() && deque.size() == length - 1;
 explorer.summary(result);
 }
 public void removeFromEmpty() {
 String prefix = "removeFromEmpty";
 Deque<Integer> deque = new StringDeque<>();
 explorer.of(prefix);
 boolean result = true;
 try {
 deque.remove();
 result = false;
 } catch(NoSuchElementException e) {
 System.err.println(prefix + ": deque is empty");
 }
 explorer.summary(result);
 }
 public void removeLast() {
 int length = 5;
 Deque<Integer> deque = deque(length);
 explorer.of("removeLast");
 boolean result = deque.removeLast() == 4 && deque.size() == length - 1;
 explorer.summary(result);
 }
 public void removeLastSingleElement() {
 Deque<Integer> deque = deque(1);
 explorer.of("removeLastSingleElement");
 boolean result = deque.removeLast() == 0 && deque.size() == 0;
 explorer.summary(result);
 }
 public void removeLastFromEmpty() {
 String prefix = "removeLastFromEmpty";
 Deque<Integer> deque = new StringDeque<>();
 explorer.of(prefix);
 boolean result = true;
 try {
 deque.removeLast();
 result = false;
 } catch(NoSuchElementException e) {
 System.err.println(prefix + ": deque is empty");
 }
 explorer.summary(result);
 }
 public void contains() {
 Deque<Integer> deque = deque(7);
 explorer.of("contains");
 boolean result = deque.contains(6);
 explorer.summary(result);
 }
 public void notContains() {
 Deque<Integer> deque = deque(3);
 explorer.of("notContains");
 boolean result = deque.contains(7);
 explorer.summary(result == false);
 }
 public void retainAll() {
 Deque<Integer> deque = deque(5);
 List<Integer> retained = toListFrom(5, 2, 1, 7);
 explorer.of("retainAll");
 deque.retainAll(retained);
 boolean result = deque.size() == 2;
 explorer.summary(result);
 }
 public void retainAllMultipleOccurences() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 List<Integer> retained = toListFrom(2, 1);
 explorer.of("retainAllMultipleOccurences");
 for ( int i = 0; i < size; i++ ) { deque.addFirst(i); }
 boolean result = deque.retainAll(retained) && deque.size() == 4;
 explorer.summary(result);
 }
 public void retainAllEmptyCollection() {
 Deque<Integer> deque = deque(5);
 List<Integer> retained = new ArrayList<>();
 explorer.of("retainAllEmptyCollection");
 boolean result = !deque.retainAll(retained) && deque.size() == 5;
 explorer.summary(result);
 }
 public void retainAllEmpty() {
 Deque<Integer> deque = deque(0);
 List<Integer> retained = toListFrom(5, 2, 1, 7);
 explorer.of("retainAllEmpty");
 boolean result = deque.retainAll(retained) == false && deque.size() == 0;
 explorer.summary(result);
 }
 public void pollFirst() {
 int size = 2;
 Deque<Integer> deque = deque(size);
 explorer.of("pollFirst");
 Integer first = deque.pollFirst();
 boolean result = first.intValue() == 0 && deque.size() == size - 1;
 explorer.summary(result);
 }
 public void pollFirstFromEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("pollFirstFromEmpty");
 Integer first = deque.pollFirst();
 boolean result = first == null && deque.size() == 0;
 explorer.summary(result);
 }
 public void poll() {
 int size = 2;
 Deque<Integer> deque = deque(size);
 explorer.of("poll");
 Integer first = deque.poll();
 boolean result = first.intValue() == 0 && deque.size() == size - 1;
 explorer.summary(result);
 }
 public void pollFromEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("pollFromEmpty");
 Integer first = deque.poll();
 boolean result = first == null && deque.size() == 0;
 explorer.summary(result);
 }
 public void pollLast() {
 int size = 2;
 Deque<Integer> deque = deque(size);
 explorer.of("pollLast");
 Integer first = deque.pollLast();
 boolean result = first.intValue() == 1 && deque.size() == size - 1;
 explorer.summary(result);
 }
 public void pollLastFromEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("pollLastFromEmpty");
 Integer first = deque.pollLast();
 boolean result = first == null && deque.size() == 0;
 explorer.summary(result);
 }
 public void getFirst() {
 int size = 1;
 Deque<Integer> deque = deque(size);
 explorer.of("getFirst");
 boolean result = deque.getFirst().intValue() == 0 && deque.size() == size;
 explorer.summary(result);
 }
 public void getFirstFromEmpty() {
 String prefix= "getFirstFromEmpty";
 int size = 0;
 Deque<Integer> deque = deque(size);
 explorer.of(prefix);
 boolean result = false;
 try {
 deque.getFirst();
 } catch(NoSuchElementException e) {
 System.err.println(prefix + ": deque is empty");
 result = deque.size() == size;
 }
 explorer.summary(result);
 }
 public void element() {
 int size = 1;
 Deque<Integer> deque = deque(size);
 explorer.of("element");
 boolean result = deque.element().intValue() == 0 && deque.size() == size;
 explorer.summary(result);
 }
 public void elementFromEmpty() {
 String prefix= "elementFromEmpty";
 int size = 0;
 Deque<Integer> deque = deque(size);
 explorer.of(prefix);
 boolean result = false;
 try {
 deque.element();
 } catch(NoSuchElementException e) {
 System.err.println(prefix + ": deque is empty");
 result = deque.size() == size;
 }
 explorer.summary(result);
 }
 public void peek() {
 int size = 1;
 Deque<Integer> deque = deque(size);
 explorer.of("peek");
 boolean result = deque.peek().intValue() == 0 && deque.size() == size;
 explorer.summary(result);
 }
 public void peekFromEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("peekFromEmpty");
 boolean result = deque.peek() == null && deque.size() == 0;
 explorer.summary(result);
 }
 public void getLast() {
 int size = 2;
 Deque<Integer> deque = deque(size);
 explorer.of("letLast");
 boolean result = deque.getLast().intValue() == 1 && deque.size() == size;
 explorer.summary(result);
 }
 public void getLastFromEmpty() {
 String prefix = "getLastFromEmpty";
 int size = 0;
 Deque<Integer> deque = deque(size);
 explorer.of(prefix);
 boolean result = false;
 try {
 deque.getLast();
 } catch(NoSuchElementException e) {
 System.err.println(prefix + ": deque is empty");
 result = deque.size() == size;
 }
 explorer.summary(result);
 }
 public void peekFirst() {
 int size = 1;
 Deque<Integer> deque = deque(size);
 explorer.of("peekFirst");
 boolean result = deque.peekFirst().intValue() == 0 && deque.size() == size;
 explorer.summary(result);
 }
 public void peekFirstFromEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("peekFirstFromEmpty");
 boolean result = deque.peekFirst() == null && deque.size() == 0;
 explorer.summary(result);
 }
 public void peekLast() {
 int size = 2;
 Deque<Integer> deque = deque(size);
 explorer.of("peekLast");
 boolean result = deque.peekLast().intValue() == 1 && deque.size() == size;
 explorer.summary(result);
 }
 public void peekLastFromEmpty() {
 int size = 0;
 Deque<Integer> deque = deque(size);
 explorer.of("peekLastFromEmpty");
 boolean result = deque.peekLast() == null && deque.size() == size;
 explorer.summary(result);
 }
 public void removeFirstOccurrence() {
 Deque<Integer> deque = deque(2);
 explorer.of("removeFirstOccurrence");
 deque.addFirst(0);
 boolean result = deque.removeFirstOccurrence(0) && deque.size() == 2;
 explorer.summary(result);
 }
 public void removeFirstOccurrenceLastElement() {
 Deque<Integer> deque = deque(2);
 explorer.of("removeFirstOccurrenceLastElement");
 deque.addLast(2);
 boolean result = deque.removeFirstOccurrence(2) && deque.size() == 2;
 explorer.summary(result);
 }
 public void removeFirstOccurrenceFromEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("removeFirstOccurrenceFromEmpty");
 boolean result = !deque.removeFirstOccurrence(0) && deque.size() == 0;
 explorer.summary(result);
 }
 public void removeObject() {
 Deque<Integer> deque = deque(2);
 deque.addFirst(0);
 explorer.of("removeObject");
 boolean result = deque.remove(0) && deque.size() == 2;
 explorer.summary(result);
 }
 public void removeObjectFromEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("removeObjectFromEmpty");
 boolean result = !deque.remove(0) && deque.size() == 0;
 explorer.summary(result);
 }
 public void removeLastOccurrence() {
 Deque<Integer> deque = deque(2);
 deque.addLast(0);
 String intended = toString(new Integer[]{ 0, 1 });
 explorer.of("removeLastOccurrence");
 boolean result = deque.removeLastOccurrence(0) && deque.size() == 2
 && intended.equals(toString(deque.toArray()));
 explorer.summary(result);
 }
 public void removeLastOccurrenceFromEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("removeLastOccurrenceFromEmpty");
 boolean result = !deque.removeLastOccurrence(0) && deque.size() == 0;
 explorer.summary(result);
 }
 public void size() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("size");
 boolean result = deque.size() == size;
 explorer.summary(result);
 }
 public void iterator() {
 Deque<Integer> deque = deque(5);
 explorer.of("iterator");
 boolean result = true;
 int index = 0;
 for ( Iterator<Integer> i = deque.iterator(); i.hasNext(); ) {
 result = result && i.next() == index++;
 }
 explorer.summary(result);
 }
 public void iteratorOverflown() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("iteratorOverflown");
 boolean result = true, excepted = false;
 int index = 0;
 for ( Iterator<Integer> i = deque.iterator(); index < size + 2; ) {
 try {
 result = result && i.next() == index;
 } catch(NoSuchElementException e) {
 excepted = true;
 }
 index++;
 }
 explorer.summary(result);
 }
 public void iteratorOfEmpty() {
 Deque<Integer> deque = deque(0);
 Iterator<Integer> i = deque.iterator();
 explorer.of("iteratorOfEmpty");
 boolean result = !i.hasNext(), excepted = false;
 try { i.next(); } catch(NoSuchElementException e) { excepted = true; }
 explorer.summary(result);
 }
 public void iteratorRemove() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("iteratorRemove");
 Iterator<Integer> iterator = deque.iterator();
 iterator.next();
 iterator.remove();
 boolean result = deque.size() == size - 1;
 explorer.summary(result);
 }
 public void iteratorRemoveFirst() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("iteratorRemoveFirst");
 Iterator<Integer> i = deque.iterator();
 i.next();
 i.remove();
 boolean result = deque.size() == size - 1 && i.next() == size - deque.size();
 explorer.summary(result);
 }
 public void iteratorRemoveAll() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("iteratorRemoveAll");
 Iterator<Integer> i = deque.iterator();
 boolean result = removeAll(deque, i);
 explorer.summary(result);
 }
 private boolean removeAll(Deque<Integer> deque, Iterator<Integer> i) {
 int pivot = 2;
 while(i.hasNext() ) { if (i.next() != pivot) { i.remove(); } }
 boolean result = deque.size() == 1
 && deque.descendingIterator().next() == pivot
 && deque.removeFirst() == pivot
 && deque.size() == 0;
 return result;
 }
 public void iteratorOfOneRemove() {
 Deque<Integer> deque = deque(1);
 explorer.of("iteratorOfOneRemove");
 Iterator<Integer> i = deque.iterator();
 i.next();
 i.remove();
 boolean result = deque.size() == 0;
 explorer.summary(result);
 }
 public void iteratorRemoveWithoutCallingNext() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("iteratorRemoveWithoutCallingNext");
 deque.iterator().remove();
 boolean result = deque.size() == size;
 explorer.summary(result);
 }
 public void descendingIterator() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("descendingIterator");
 boolean result = true;
 int index = size - 1;
 for ( Iterator<Integer> i = deque.descendingIterator(); i.hasNext(); ) {
 result = result && i.next() == index--;
 }
 explorer.summary(result);
 }
 public void descendingIteratorOverflown() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("descendingIteratorOverflown");
 boolean result = true, excepted = false;
 int index = size + 2;
 for ( Iterator<Integer> i = deque.descendingIterator(); index > -1; ) {
 try {
 result = result && i.next() == index - 3;
 } catch(NoSuchElementException e) {
 excepted = true;
 }
 index--;
 }
 explorer.summary(result);
 }
 public void descendingIteratorOfEmpty() {
 Deque<Integer> deque = deque(0);
 explorer.of("descendingIteratorOfEmpty");
 Iterator<Integer> i = deque.descendingIterator();
 boolean result = !i.hasNext(), excepted = false;
 try { i.next(); } catch(NoSuchElementException e) { excepted = true; }
 explorer.summary(result && excepted);
 }
 public void descendingIteratorRemove() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("descendingIteratorRemove");
 Iterator<Integer> i = deque.descendingIterator();
 i.next();
 i.remove();
 boolean result = deque.size() == size - 1;
 explorer.summary(result);
 }
 public void descendingIteratorRemoveFirst() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("descendingIteratorRemoveFirst");
 Iterator<Integer> i = deque.descendingIterator();
 i.next();
 i.remove();
 boolean result = deque.size() == size - 1 && i.next() == size - 2;
 explorer.summary(result);
 }
 public void descendingIteratorRemoveAll() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("descendingIteratorRemoveAll");
 Iterator<Integer> i = deque.descendingIterator();
 boolean result = removeAll(deque, i);
 explorer.summary(result);
 }
 public void descendingIteratorOfOneRemove() {
 Deque<Integer> deque = deque(1);
 explorer.of("descendingIteratorOfOneRemove");
 Iterator<Integer> i = deque.descendingIterator();
 i.next();
 i.remove();
 boolean result = deque.size() == 0;
 explorer.summary(result);
 }
 public void descendingIteratorRemoveWithoutCallingNext() {
 int size = 5;
 Deque<Integer> deque = deque(size);
 explorer.of("descendingIteratorRemoveWithoutCallingNext");
 deque.descendingIterator().remove();
 boolean result = deque.size() == size;
 explorer.summary(result);
 }
 public void overall() { explorer.overall(); }
 private String stringed(int length) {
 Integer[] intended = new Integer[length];
 for (int i = 0; i < length; i++) { intended[i] = i; }
 return toString(intended);
 }
 private Deque<Integer> deque(int size) {
 Deque<Integer> deque = new StringDeque<>();
 for (int i = 0; i < size; i++) { deque.addLast(i); }
 return deque;
 }
 private Deque<Integer> deque(int size, int capacity) {
 Deque<Integer> deque = new StringDeque<>(capacity);
 for (int i = 0; i < size; i++) { deque.addLast(i); }
 return deque;
 }
 private String toString(Object[] array) {
 if (array == null || array.length == 0) { return ""; }
 StringBuilder result = new StringBuilder("[");
 String separator = ", ";
 for (int i = 0; i < array.length; i++) {
 result.append(array[i]).append(separator);
 }
 result.delete(result.length() - separator.length(), result.length());
 return result.append("]").toString();
 }
 private List<Object> toList(Object ... objects) {
 List list = new ArrayList();
 for (int i = 0; i < objects.length; i++) { list.add(objects[i]); }
 return list;
 }
 private List<Integer> toListFrom(int ... objects) {
 List<Integer> list = new ArrayList<>();
 for (int i = 0; i < objects.length; i++) { list.add(objects[i]); }
 return list;
 }
}
asked Oct 1 at 16:46
\$\endgroup\$
2
  • \$\begingroup\$ Thank you for the "showcase" code; that is helpful context. // fore conveniently has the same number of characters as next, so some code will vertically align onscreen. But it's a bit unusual. Consider renaming to another 4-character identifier, the usual prev, for "previous". \$\endgroup\$ Commented Oct 1 at 16:58
  • 2
    \$\begingroup\$ @J_H There are more oddly named variables, you could catch a few and write your suggestions in an answer instead of in the comments. \$\endgroup\$ Commented Oct 1 at 18:49

1 Answer 1

1
\$\begingroup\$

While the Strategy interface is in acord with strategy design pattern its implementations are command design pattern since the implementations call behaviours of the reference hold by the field initialised by the constructor. Adding to the method defined by the Strategy interface additional argument to pass the object the field holds reference to could be the solution to avoid confusions about the design pattern intended to use, that is command pattern since calling behaviour of objects that change their state is the difference between the two conflated by the implementation to review design patterns.

The retainAll method could be improved by defining a command that traverses the string of POJOs removing the POJOs the passed in collection doesn’t contain:

private static class RetainAll implements Strategy {
 private Of of;
 public RetainAll(Of context) { of = context; }
 @Override
 public boolean element(Object element) {
 Collection retaineds = (Collection) element;
 boolean result = false; 
 Bind bind = of.bindings;
 while (!of.isEmpty() && bind != null) {
 if (!retaineds.contains(bind.element)) {
 bind = bind == of.bindings ? of.peakless()
 : Of.remove(bind, bind.next);
 result = true;
 } else {
 bind = bind.next;
 }
 }
 return result;
 }
}
private static class Strategies {
 private Strategy prepend, append,containsNull, contains, peakless
 , nullPeakless, nullless, remove, allNullPeakless
 , allPeakless,lastRemove, lastNullRemove, allless
 , allNullless, retainAll;
 public Strategies(Of of) {
 prepend = new Prepend(of);
 append = new Append(of);
 peakless = new Peakless(of);
 nullPeakless = new NullPeakless(of);
 nullless = new Nullless(of);
 remove = new Remove(of);
 allless = new Allless(of);
 allNullless = new AllNullless(of);
 allNullPeakless = new AllNullPeakless(of);
 allPeakless = new AllPeakless(of);
 lastRemove = new LastRemove(of);
 lastNullRemove = new LastNullRemove(of);
 containsNull = new ContainsNull(of);
 contains = new Contains(of);
 retainAll = new RetainAll(of);
 }
 public Strategy append() { return append; }
 public Strategy prepend() { return prepend; }
 public Strategy peakless(Object removed) {
 return removed == null ? nullPeakless : peakless;
 }
 public Strategy remove(Object removed) {
 return removed == null ? nullless : remove;
 }
 public Strategy allPeakless(Object removed) {
 return removed == null ? allNullPeakless : allPeakless;
 }
 public Strategy allless(Object removed) {
 return removed == null ? allNullless : allless;
 }
 public Strategy lastRemove(Object removed) {
 return removed == null ? lastNullRemove : lastRemove;
 }
 public Strategy contains(Object contained) {
 return contained == null ? containsNull : contains;
 }
 public Strategy retainAll() { return retainAll; }
}

...changes that would turn the implementation of retainAll method to:

@Override
public boolean retainAll(Collection<?> c) {
 if (c.isEmpty() || isEmpty()) { return false; }
 return strategies.retainAll().element(c);
}

Although the purpose of the requested review is the java.util.Deque implementation could be helpful to know the Bulk and TimedBulk explorers, from the usage showcase code snippet, print twice the summary of the last exploration, while TimedState runner prints the result, when that is false, and the summary when the result is true. Code snippet attempting to change mentioned behaviours:

private static class TimedState implements Runner {
 private String text;
 private long start, elapsed;
 public TimedState(String explored) {
 text = explored;
 start = System.nanoTime();
 }
 @Override
 public void summary(boolean result) {
 elapsed = (System.nanoTime() - start) / 1000;
 }
 public void print(boolean result) {
 String string = result ? "Passed" : "Failed";
 String message = text + " ... " + string
 + " [elapsed: " + elapsed + " ms]";
 if (result) {
 System.out.println(message);
 } else {
 System.err.println(message);
 }
 }
}
private static class Bulk implements Explorer {
 private Plain[] runners = {};
 private boolean[] results = {};
 public void of(String text) { run(new Plain(text)); }
 public void run(Plain runner) { runners = append(runner, runners); }
 private Plain[] append(Plain runner, Plain ... runners) {
 Plain[] runees = new Plain[runners.length + 1];
 runees[runees.length - 1] = runner;
 for (int i = 0; i < runees.length - 1; i++) {
 runees[i] = runners[i];
 }
 return runees;
 }
 @Override
 public void summary(boolean result) {
 boolean[] booleans = new boolean[results.length + 1];
 booleans[booleans.length - 1] = result;
 for (int i = 0; i < results.length; i++) {
 booleans[i] = results[i];
 }
 results = booleans;
 }
 @Override
 public void overall() {
 if (results.length == 0) { return; }
 int index = results.length - 1;
 boolean passed = results[index];
 for (int i = index; i > -1; i--) {
 passed = passed && results[i];
 runners[i].summary(results[i]);
 }
 overall(passed);
 }
 @Override
 public void overall(boolean result) {
 if (result) {
 System.out.println();
 System.out.println("Pass.");
 } else {
 System.err.println();
 System.err.println("Fail.");
 }
 }
}
private static class TimedBulk implements Explorer {
 private TimedState[] runners = {};
 private boolean[] results = {};
 public void of(String text) { run(new TimedState(text)); }
 public void run(TimedState runee) { runners = append(runee, runners); }
 private TimedState[] append(TimedState runner, TimedState ... runners) {
 TimedState[] runees = new TimedState[runners.length + 1];
 runees[runees.length - 1] = runner;
 for (int i = 0; i < runees.length - 1; i++) {
 runees[i] = runners[i];
 }
 return runees;
 }
 @Override
 public void summary(boolean result) {
 boolean[] booleans = new boolean[results.length + 1];
 booleans[booleans.length - 1] = result;
 for (int i = 0; i < results.length; i++) {
 booleans[i] = results[i];
 runners[i].summary(result);
 }
 results = booleans;
 }
 @Override
 public void overall() {
 if (results.length == 0) { return; }
 int index = results.length - 1;
 boolean passed = results[index];
 for (int i = index; i > -1; i--) {
 passed = passed && results[i];
 runners[i].print(results[i]);
 }
 overall(passed);
 }
 @Override
 public void overall(boolean result) {
 if (result) {
 System.out.println();
 System.out.println("Pass.");
 } else {
 System.err.println();
 System.err.println("Fail.");
 }
 }
}
answered Oct 2 at 16:05
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.