Add some files for Deque

This commit is contained in:
dota17 2019-11-29 15:27:28 +08:00
parent 138898ce62
commit d682042aaa
8 changed files with 1739 additions and 1 deletions

View File

@ -0,0 +1,521 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.deque;
import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Iterator;
import java.util.Deque;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* Decorates another {@link Deque} to support blocking operations that wait for the deque
* to become non-empty when retrieving an element, and wait for space to become available
* in the deque when storing an element if the decorated deque has a capacity limit.
* <p>
* This deque exists to support blocking operations for the decorated deque. It is thread
* safe.
* </p>
*
* @param <E> the type of elements held in this deque
* @since 4.5
*/
public class BlockingDeque<E> extends AbstractCollection<E> implements Deque<E>, Serializable {
final Deque<E> deque;
final ReentrantLock lock = new ReentrantLock();
/** Condition for waiting takes */
private final Condition notEmpty = lock.newCondition();
/** Condition for waiting puts */
private final Condition notFull = lock.newCondition();
/**
* Factory method to create a blocking deque.
*
* @param <E>
* the type of the elements in the deque
* @param deque
* the deque to decorate, must not be null
* @return a new blocking Deque
* @throws NullPointerException
* if deque is null
*/
public static <E> BlockingDeque<E> blockingDeque(final Deque<E> deque) {
return new BlockingDeque<>(deque);
}
/**
* Constructor that wraps (not copies).
*
* @param deque
* the deque to decorate, must not be null
* @throws NullPointerException
* if deque is null
*/
public BlockingDeque(final Deque<E> deque) {
if (deque == null) {
throw new NullPointerException();
}
this.deque = deque;
}
/**
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
*/
@Override
public void addFirst(final E e) {
if (!offerFirst(e))
throw new IllegalStateException("Deque is full");
}
/**
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
*/
@Override
public void addLast(final E e) {
if (!offerLast(e))
throw new IllegalStateException("Deque is full");
}
/**
* @return {@code true} if the element was added to this deque, else
* {@code false}
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
*/
@Override
public boolean offerFirst(final E e) {
lock.lock();
try {
boolean r;
if ((r = deque.offerFirst(e)) == true)
notEmpty.signal();
return r;
} catch (Exception ex) {
throw ex;
} finally {
lock.unlock();
}
}
/**
* @return {@code true} if the element was added to this deque, else
* {@code false}
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
*/
@Override
public boolean offerLast(final E e) {
lock.lock();
try {
boolean r;
if ((r = deque.offerLast(e)) == true)
notEmpty.signal();
return r;
} catch (Exception ex) {
throw ex;
} finally {
lock.unlock();
}
}
/**
* Inserts the specified element at the front of this deque. It will be
* blocked and wait for space to become available if the deque is full.
*
* @param e the element to add
* @throws InterruptedException if interrupted while waiting
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
*/
public void putFirst(final E e) throws InterruptedException {
lock.lock();
try {
while (!deque.offerFirst(e))
notFull.await();
notEmpty.signal();
} finally {
lock.unlock();
}
}
/**
* Inserts the specified element at the end of this deque. It will be
* blocked and wait for space to become available if the deque is full.
*
* @param e the element to add
* @throws InterruptedException if interrupted while waiting
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
*/
public void putLast(final E e) throws InterruptedException {
lock.lock();
try {
while (!deque.offerLast(e))
notFull.await();
notEmpty.signal();
} finally {
lock.unlock();
}
}
@Override
public E removeFirst() {
lock.lock();
try {
E e;
if ((e = deque.removeFirst()) != null)
notFull.signal();
return e;
} finally {
lock.unlock();
}
}
@Override
public E removeLast() {
lock.lock();
try {
E e;
if ((e = deque.removeLast()) != null)
notFull.signal();
return e;
} finally {
lock.unlock();
}
}
/**
* Retrieves and removes the first element of this deque, waiting
* if necessary until an element becomes available.
*
* @return the head of this deque
* @throws InterruptedException if interrupted while waiting
*/
public E takeFirst() throws InterruptedException {
lock.lock();
try {
while (deque.size() == 0)
notEmpty.await();
E x = deque.removeFirst();
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
/**
* Retrieves and removes the last element of this deque, waiting
* if necessary until an element becomes available.
*
* @return the tail of this deque
* @throws InterruptedException if interrupted while waiting
*/
public E takeLast() throws InterruptedException {
lock.lock();
try {
while (deque.size() == 0)
notEmpty.await();
E x = deque.removeLast();
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
@Override
public E pollFirst() {
lock.lock();
try {
E e;
if ((e = deque.pollFirst()) != null)
notFull.signal();
return e;
} finally {
lock.unlock();
}
}
@Override
public E pollLast() {
lock.lock();
try {
E e;
if ((e = deque.pollLast()) != null)
notFull.signal();
return e;
} finally {
lock.unlock();
}
}
@Override
public E getFirst() {
lock.lock();
try {
return deque.getFirst();
} finally {
lock.unlock();
}
}
@Override
public E getLast() {
lock.lock();
try {
return deque.getLast();
} finally {
lock.unlock();
}
}
@Override
public E peekFirst() {
lock.lock();
try {
return deque.peekFirst();
} finally {
lock.unlock();
}
}
@Override
public E peekLast() {
lock.lock();
try {
return deque.peekLast();
} finally {
lock.unlock();
}
}
@Override
public boolean removeFirstOccurrence(final Object o) {
lock.lock();
try {
boolean r;
if ((r = deque.removeFirstOccurrence(o)) == true)
notEmpty.signal();
return r;
} finally {
lock.unlock();
}
}
@Override
public boolean removeLastOccurrence(final Object o) {
lock.lock();
try {
boolean r;
if ((r = deque.removeLastOccurrence(o)) == true)
notEmpty.signal();
return r;
} finally {
lock.unlock();
}
}
@Override
public boolean add(final E e) {
addLast(e);
return true;
}
@Override
public boolean offer(final 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 void push(final E e) {
addFirst(e);
}
@Override
public E pop() {
return removeFirst();
}
@Override
public boolean remove(final Object o) {
return removeFirstOccurrence(o);
}
@Override
public boolean containsAll(final Collection<?> c) {
lock.lock();
try {
return deque.containsAll(c);
} finally {
lock.unlock();
}
}
@Override
public boolean addAll(final Collection<? extends E> c) {
lock.lock();
try {
boolean r;
if ((r = deque.addAll(c)) == true)
notEmpty.signalAll();
return r;
} finally {
lock.unlock();
}
}
@Override
public boolean removeAll(final Collection<?> c) {
lock.lock();
try {
boolean r;
if ((r = deque.removeAll(c)) == true)
notFull.signalAll();
return r;
} finally {
lock.unlock();
}
}
@Override
public boolean retainAll(final Collection<?> c) {
lock.lock();
try {
boolean r;
r = deque.retainAll(c);
if (r == true) {
notFull.signalAll();
}
return r;
} finally {
lock.unlock();
}
}
@Override
public void clear() {
lock.lock();
try {
deque.clear();
notFull.signalAll();
} finally {
lock.unlock();
}
}
@Override
public boolean contains(final Object o) {
lock.lock();
try {
return deque.contains(o);
} finally {
lock.unlock();
}
}
@Override
public int size() {
lock.lock();
try {
return deque.size();
} finally {
lock.unlock();
}
}
@Override
public boolean isEmpty() {
lock.lock();
try {
return deque.isEmpty();
} finally {
lock.unlock();
}
}
@Override
public Iterator<E> iterator() {
return deque.iterator();
}
@Override
public Object[] toArray() {
lock.lock();
try {
return deque.toArray();
} finally {
lock.unlock();
}
}
@Override
public <T> T[] toArray(final T[] a) {
lock.lock();
try {
return deque.toArray(a);
} finally {
lock.unlock();
}
}
@Override
public Iterator<E> descendingIterator() {
return deque.descendingIterator();
}
}

View File

@ -0,0 +1,440 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.deque;
import org.apache.commons.collections4.BoundedCollection;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*;
/**
* CircularDeque is a deque with a fixed size that replaces its oldest
* element if full.
* <p>
* The removal order of a {@link CircularDeque} is based on the
* insertion order; elements are removed in the same order in which they
* were added. The iteration order is the same as the removal order.
* </p>
* <p>
* The {@link #add(Object)}, {@link #remove()}, {@link #peek()}, {@link #poll},
* {@link #offer(Object)} operations all perform in constant time.
* All other operations perform in linear time or worse.
* </p>
* <p>
* This deque prevents null objects from being added.
* </p>
*
* @param <E> the type of elements in this collection
* @since 4.5
*/
public class CircularDeque<E> extends AbstractCollection<E>
implements Deque<E>, BoundedCollection<E>, Serializable {
/** Underlying storage array. */
private transient E[] elements;
/** Array index of first (oldest) deque element. */
private transient int head = 0;
/**
* Index mod maxElements of the array position following the last deque
* element. Deque elements start at elements[head] and "wrap around"
* elements[maxElements-1], ending at elements[decrement(tail)].
* For example, elements = {c,a,b}, start=1, end=1 corresponds to
* the deque [a,b,c].
*/
private transient int tail = 0;
/** Flag to indicate if the deque is currently full. */
private transient boolean full = false;
/** Capacity of the deque. */
private final int maxElements;
/**
* Constructor that creates a deque with the default size of 32.
*/
public CircularDeque() {
this(32);
}
/**
* Constructor that creates a deque with the specified size.
*
* @param size the size of the deque (cannot be changed)
* @throws IllegalArgumentException if the size is &lt; 1
*/
@SuppressWarnings("unchecked")
public CircularDeque(final int size) {
if (size <= 0) {
throw new IllegalArgumentException("The size must be greater than 0");
}
elements = (E[]) new Object[size];
maxElements = elements.length;
}
/**
* Constructor that creates a deque from the specified collection.
* The collection size also sets the deque size.
*
* @param coll the collection to copy into the deque, may not be null
* @throws NullPointerException if the collection is null
*/
public CircularDeque(final Collection<? extends E> coll) {
this(coll.size());
addAll(coll);
}
/**
* Write the deque out using a custom routine.
*
* @param out the output stream
* @throws IOException if an I/O error occurs while writing to the output stream
*/
private void writeObject(final ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeInt(size());
for (final E e : this) {
out.writeObject(e);
}
}
/**
* Read the deque in using a custom routine.
*
* @param in the input stream
* @throws IOException if an I/O error occurs while writing to the output stream
* @throws ClassNotFoundException if the class of a serialized object can not be found
*/
@SuppressWarnings("unchecked")
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
elements = (E[]) new Object[maxElements];
final int size = in.readInt();
for (int i = 0; i < size; i++) {
elements[i] = (E) in.readObject();
}
head = 0;
full = size == maxElements;
if (full) {
tail = 0;
} else {
tail = size;
}
}
/**
* Returns true if this deque is empty; false otherwise.
*
* @return true if this deque is empty
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* Returns {@code true} if the capacity limit of this deque has been reached,
* i.e. the number of elements stored in the deque equals its maximum size.
*
* @return {@code true} if the capacity limit has been reached, {@code false} otherwise
* @since 4.5
*/
public boolean isAtFullCapacity() {
return size() == maxElements;
}
/**
* Increase the internal index.
*
* @param index the index to increment
* @return the updated index
*/
private int indexIncrease(int index) {
index++;
if (index >= maxElements) {
index = 0;
}
return index;
}
/**
* Decrease the internal index.
*
* @param index the index to decrement
* @return the updated index
*/
private int decreaseIndex(int index) {
index--;
if (index < 0) {
index = maxElements - 1;
}
return index;
}
/**
* Adds the given element before the head of this deque. If the deque is full,
* the tail element will be overridden so that a new element can be inserted.
*
* @param e the element to add
*/
@Override
public void addFirst(final E e) {
if (isAtFullCapacity()) {
remove();
}
if (head == 0) {
head = maxElements - 1;
} else {
head--;
}
elements[head] = e;
if (tail == head) {
full = true;
}
}
/**
* Adds the given element at the tail of this deque. If the deque is full,
* the head element will be overridden so that a new element can be inserted.
*
* @param e the element to add
*/
@Override
public void addLast(final E e) {
if (isAtFullCapacity()) {
removeFirst();
}
elements[tail++] = e;
if (tail >= maxElements) {
tail = 0;
}
if (tail == head) {
full = true;
}
}
@Override
public boolean offerFirst(final E e) {
addFirst(e);
return true;
}
@Override
public boolean offerLast(final E e) {
addLast(e);
return true;
}
@Override
public E removeFirst() {
if (isEmpty()) {
throw new NoSuchElementException("queue is empty");
}
final E element = elements[head];
elements[head++] = null;
if (head >= maxElements) {
head = 0;
}
full = false;
return element;
}
@Override
public E removeLast() {
if (isEmpty()) {
throw new NoSuchElementException("queue is empty");
}
final E element = elements[tail];
elements[tail--] = null;
if (tail < 0) {
tail = maxElements - 1;
}
full = false;
return element;
}
@Override
public E pollFirst() {
if (isEmpty()) {
return null;
}
return removeFirst();
}
@Override
public E pollLast() {
if (isEmpty()) {
return null;
}
return removeLast();
}
@Override
public E getFirst() {
if (isEmpty()) {
throw new NoSuchElementException("deque is empty");
}
return elements[head];
}
@Override
public E getLast() {
if (isEmpty()) {
throw new NoSuchElementException("deque is empty");
}
return elements[decreaseIndex(tail)];
}
@Override
public E peekFirst() {
if (isEmpty()) {
return null;
}
return elements[head];
}
@Override
public E peekLast() {
if (isEmpty()) {
return null;
}
return elements[decreaseIndex(tail)];
}
@Override
public boolean removeFirstOccurrence(final Object o) {
int mask = elements.length - 1;
int i = head;
Object x;
while ((x = elements[i]) != null) {
if (Objects.equals(o,x)) {
delete(i);
ArrayDeque;
return true;
}
i = (i + 1) & mask;
}
return false;
}
@Override
public boolean removeLastOccurrence(final Object o) {
return false;
}
@Override
public boolean offer(final E e) {
return false;
}
@Override
public E remove() {
return null;
}
@Override
public E poll() {
return null;
}
@Override
public E element() {
return null;
}
@Override
public E peek() {
return null;
}
@Override
public void push(final E e) {
}
@Override
public E pop() {
return null;
}
/**
* Returns the number of elements stored in the deque.
*
* @return this deque's size
*/
@Override
public int size() {
int size = 0;
if (tail < head) {
size = maxElements - head + tail;
} else if (tail == head) {
size = full ? maxElements : 0;
} else {
size = tail - head;
}
return size;
}
/**
* {@inheritDoc}
* <p>
* A {@code CircularDeque} can never be full, thus this returns always
* {@code false}.
*
* @return always returns {@code false}
*/
@Override
public boolean isFull() {
return false;
}
@Override
public int maxSize() {
return 0;
}
@Override
public Iterator<E> iterator() {
return null;
}
@Override
public Iterator<E> descendingIterator() {
return null;
}
}

View File

@ -0,0 +1,213 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.deque;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.collection.PredicatedCollection;
import java.util.Deque;
import java.util.Iterator;
/**
* Decorates another {@link Deque} to validate that additions
* match a specified predicate.
* <p>
* This deque exists to provide validation for the decorated deque.
* It is normally created to decorate an empty deque.
* If an object cannot be added to the deque, an IllegalArgumentException is thrown.
* </p>
* <p>
* One usage would be to ensure that no null entries are added to the deque.
* </p>
* <pre>Deque deque = PredicatedDeque.predicatedDeque(new UnboundedFifoDeque(), NotNullPredicate.INSTANCE);</pre>
*
* @param <E> the type of elements held in this deque
* @since 4.5
*/
public class PredicatedDeque<E> extends PredicatedCollection<E> implements Deque<E> {
/**
* Factory method to create a predicated (validating) deque.
* <p>
* If there are any elements already in the deque being decorated, they
* are validated.
*
* @param <E> the type of the elements in the deque
* @param deque the deque to decorate, must not be null
* @param predicate the predicate to use for validation, must not be null
* @return a new predicated deque
* @throws NullPointerException if deque or predicate is null
* @throws IllegalArgumentException if the deque contains invalid elements
*/
public static <E> PredicatedDeque<E> predicatedDeque(final Deque<E> deque,
final Predicate<? super E> predicate) {
return new PredicatedDeque<>(deque, predicate);
}
/**
* Constructor that wraps (not copies).
* <p>
* If there are any elements already in the collection being decorated, they
* are validated.
*
* @param deque the collection to decorate, must not be null
* @param predicate the predicate to use for validation, must not be null
* @throws NullPointerException if collection or predicate is null
* @throws IllegalArgumentException if the collection contains invalid elements
*/
protected PredicatedDeque(Deque<E> deque, Predicate<? super E> predicate) {
super(deque, predicate);
}
/**
* Gets the deque being decorated.
*
* @return the decorated deque
*/
@Override
protected Deque<E> decorated() {
return (Deque<E>) super.decorated();
}
/**
* Override to validate the object being added to ensure it matches
* the predicate.
*
* @param e the object being added
* @throws IllegalArgumentException if the add is invalid
*/
@Override
public void addFirst(final E e) {
validate(e);
decorated().addFirst(e);
}
@Override
public void addLast(final E e) {
validate(e);
decorated().addLast(e);
}
@Override
public boolean offerFirst(final E e) {
validate(e);
return decorated().offerFirst(e);
}
@Override
public boolean offerLast(final E e) {
validate(e);
return decorated().offerLast(e);
}
@Override
public E removeFirst() {
return decorated().removeFirst();
}
@Override
public E removeLast() {
return decorated().removeLast();
}
@Override
public E pollFirst() {
return decorated().pollFirst();
}
@Override
public E pollLast() {
return decorated().pollLast();
}
@Override
public E getFirst() {
return decorated().getFirst();
}
@Override
public E getLast() {
return decorated().getLast();
}
@Override
public E peekFirst() {
return decorated().peekFirst();
}
@Override
public E peekLast() {
return decorated().peekLast();
}
@Override
public boolean removeFirstOccurrence(final Object o) {
validate((E) o);
return decorated().removeFirstOccurrence(o);
}
@Override
public boolean removeLastOccurrence(final Object o) {
validate((E) o);
return decorated().removeLastOccurrence(o);
}
@Override
public boolean offer(final E e) {
validate(e);
return decorated().offer(e);
}
@Override
public E remove() {
return decorated().remove();
}
@Override
public E poll() {
return decorated().poll();
}
@Override
public E element() {
return decorated().element();
}
@Override
public E peek() {
return decorated().peek();
}
@Override
public void push(final E e) {
validate(e);
decorated().push(e);
}
@Override
public E pop() {
return decorated().pop();
}
@Override
public Iterator<E> descendingIterator() {
return decorated().descendingIterator();
}
}

View File

@ -0,0 +1,261 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.deque;
import org.apache.commons.collections4.collection.SynchronizedCollection;
import java.util.Deque;
import java.util.Iterator;
/**
* Decorates another {@link Deque} to synchronize its behaviour for a multi-threaded environment.
* <p>
* Methods are synchronized, then forwarded to the decorated deque. Iterators must be separately synchronized around the
* loop.
* </p>
*
* @param <E> the type of the elements in the collection
* @since 4.5
*/
public class SynchronizedDeque<E> extends SynchronizedCollection<E> implements Deque<E> {
/** Serialization version */
private static final long serialVersionUID = 1L;
/**
* Factory method to create a synchronized deque.
*
* @param <E>
* the type of the elements in the deque
* @param deque
* the deque to decorate, must not be null
* @return a new synchronized Deque
* @throws NullPointerException
* if deque is null
*/
public static <E> SynchronizedDeque<E> synchronizedDeque(final Deque<E> deque) {
return new SynchronizedDeque<>(deque);
}
/**
* Constructor that wraps (not copies).
*
* @param deque
* the deque to decorate, must not be null
* @throws NullPointerException
* if deque is null
*/
protected SynchronizedDeque(final Deque<E> deque) {
super(deque);
}
/**
* Constructor that wraps (not copies).
*
* @param deque
* the deque to decorate, must not be null
* @param lock
* the lock to use, must not be null
* @throws NullPointerException
* if deque or lock is null
*/
protected SynchronizedDeque(final Deque<E> deque, final Object lock) {
super(deque, lock);
}
/**
* Gets the deque being decorated.
*
* @return the decorated deque
*/
@Override
protected Deque<E> decorated() {
return (Deque<E>) super.decorated();
}
@Override
public E element() {
synchronized (lock) {
return decorated().element();
}
}
@Override
public boolean equals(final Object object) {
if (object == this) {
return true;
}
synchronized (lock) {
return decorated().equals(object);
}
}
@Override
public int hashCode() {
synchronized (lock) {
return decorated().hashCode();
}
}
@Override
public void addFirst(E e) {
synchronized (lock) {
decorated().addFirst(e);
}
}
@Override
public void addLast(E e) {
synchronized (lock) {
decorated().addLast(e);
}
}
@Override
public boolean offerFirst(E e) {
synchronized (lock) {
return decorated().offerFirst(e);
}
}
@Override
public boolean offerLast(E e) {
synchronized (lock) {
return decorated().offerLast(e);
}
}
@Override
public E removeFirst() {
synchronized (lock) {
return decorated().removeFirst();
}
}
@Override
public E removeLast() {
synchronized (lock) {
return decorated().removeLast();
}
}
@Override
public E pollFirst() {
synchronized (lock) {
return decorated().pollFirst();
}
}
@Override
public E pollLast() {
synchronized (lock) {
return decorated().pollLast();
}
}
@Override
public E getFirst() {
synchronized (lock) {
return decorated().getFirst();
}
}
@Override
public E getLast() {
synchronized (lock) {
return decorated().getLast();
}
}
@Override
public E peekFirst() {
synchronized (lock) {
return decorated().peekFirst();
}
}
@Override
public E peekLast() {
synchronized (lock) {
return decorated().peekLast();
}
}
@Override
public boolean removeFirstOccurrence(Object o) {
synchronized (lock) {
return decorated().removeFirstOccurrence(o);
}
}
@Override
public boolean removeLastOccurrence(Object o) {
synchronized (lock) {
return decorated().removeLastOccurrence(o);
}
}
@Override
public boolean offer(final E e) {
synchronized (lock) {
return decorated().offer(e);
}
}
@Override
public E peek() {
synchronized (lock) {
return decorated().peek();
}
}
@Override
public void push(E e) {
synchronized (lock) {
decorated().push(e);
}
}
@Override
public E pop() {
synchronized (lock) {
return decorated().pop();
}
}
@Override
public Iterator<E> descendingIterator() {
synchronized (lock) {
return decorated().descendingIterator();
}
}
@Override
public E poll() {
synchronized (lock) {
return decorated().poll();
}
}
@Override
public E remove() {
synchronized (lock) {
return decorated().remove();
}
}
}

View File

@ -0,0 +1,140 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.deque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Objects;
/**
* Extension of {@link AbstractDequeTest} for exercising the
* {@link BlockingDeque} implementation.
*
* @since 4.5
*/
public class BlockingDequeTest<E> extends AbstractDequeTest<E> {
/**
* JUnit constructor.
*
* @param testName the test class name
*/
public BlockingDequeTest(String testName) {
super(testName);
}
@Override
public Deque<E> makeObject() {
return new BlockingDeque(new LinkedList<E>());
}
public void testPutFirst() {
if (!isAddSupported()) {
return;
}
BlockingDeque<E> deque = (BlockingDeque<E>) makeObject();
final E[] elements = getFullElements();
int size = 0;
try {
for (final E element : elements) {
deque.putFirst(element);
size++;
assertEquals("Deque size should grow after add", size, deque.size());
assertTrue("Deque should contain added element", Objects.equals(element, deque.getFirst()));
}
} catch (InterruptedException ex) {
fail(ex.getMessage());
}
}
public void testPutLast() {
if (!isAddSupported()) {
return;
}
BlockingDeque<E> deque = (BlockingDeque<E>) makeObject();
final E[] elements = getFullElements();
int size = 0;
try {
for (final E element : elements) {
deque.putLast(element);
size++;
assertEquals("Deque size should grow after add", size, deque.size());
assertTrue("Deque should contain added element", Objects.equals(element, deque.getLast()));
}
} catch (InterruptedException ex) {
fail(ex.getMessage());
}
}
public void testTakeFirst() {
if (!isRemoveSupported()) {
return;
}
BlockingDeque<E> deque = new BlockingDeque<E>(makeFullCollection());
int size = deque.size();
assertTrue("Deque should contain elements",size > 0);
final E[] elements = getFullElements();
try {
for (final E element : elements) {
E e = deque.takeFirst();
size--;
assertEquals("Deque size should decrease",size, deque.size());
assertTrue(Objects.equals(element, e));
}
assertEquals("Deque should be empty", 0, deque.size());
} catch (InterruptedException ex) {
fail(ex.getMessage());
}
}
public void testTakeLast() {
if (!isRemoveSupported()) {
return;
}
BlockingDeque<E> deque = new BlockingDeque<E>(makeFullCollection());
int size = deque.size();
assertTrue("Deque should contain elements",size > 0);
final E[] elements = getFullElements();
try {
for (int i = size-1; i >= 0; i--) {
E e = deque.takeLast();
assertEquals("Deque size should decrease", i, deque.size());
assertTrue(Objects.equals(elements[i], e));
}
assertEquals("Deque should be empty", 0, deque.size());
} catch (InterruptedException ex) {
fail(ex.getMessage());
}
}
@Override
public String getCompatibilityVersion() {
return "4.5";
}
}

View File

@ -0,0 +1,95 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.deque;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.functors.NotNullPredicate;
import org.apache.commons.collections4.functors.TruePredicate;
/**
* Extension of {@link AbstractDequeTest} for exercising the
* {@link PredicatedDeque} implementation.
*
* @since 4.5
*/
public class PredicatedDequeTest<E> extends AbstractDequeTest<E> {
/**
* JUnit constructor.
*
* @param testName the test class name
*/
public PredicatedDequeTest(String testName) {
super(testName);
}
protected Predicate<E> notNullPredicate = NotNullPredicate.<E>notNullPredicate();
protected Predicate<E> truePredicate = TruePredicate.<E>truePredicate();
protected Deque<E> decorateDeque(final Deque<E> queue, final Predicate<E> predicate) {
return PredicatedDeque.predicatedDeque(queue, predicate);
}
@Override
public Deque<E> makeObject() {
return decorateDeque(new LinkedList<E>(), truePredicate);
}
@Override
public Deque<E> makeFullCollection() {
final Deque<E> deque = new LinkedList<>();
deque.addAll(Arrays.asList(getFullElements()));
return decorateDeque(deque, truePredicate);
}
public Deque<E> makeTestDeque() {
return decorateDeque(new LinkedList<E>(), notNullPredicate);
}
@SuppressWarnings("unchecked")
public void testPredicatedDeque() {
final Deque<E> deque = makeTestDeque();
assertNull(deque.peek());
try {
deque.addFirst(null);
fail("Deque.addFirst should throw IllegalArgumentException");
} catch (final IllegalArgumentException e) {
// expected
}
deque.addFirst((E) "one");
deque.addFirst((E) "two");
assertEquals("Deque get", "two", deque.pollFirst());
assertEquals("Deque get", "one", deque.pollFirst());
assertNull(deque.pollFirst());
}
@Override
public String getCompatibilityVersion() {
return "4.5";
}
}

View File

@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections4.deque;
import junit.framework.Test;
import org.apache.commons.collections4.BulkTest;
import org.junit.Ignore;
import java.util.Deque;
import java.util.LinkedList;
/**
* Extension of {@link AbstractDequeTest} for exercising the
* {@link SynchronizedDeque} implementation.
*
* @since 4.5
*/
public class SynchronizedDequeTest<E> extends AbstractDequeTest<E> {
/**
* JUnit constructor.
*
* @param testName the test class name
*/
public SynchronizedDequeTest(String testName) {
super(testName);
}
public static Test suite() {
return BulkTest.makeSuite(SynchronizedDequeTest.class);
}
@Override
public Deque<E> makeObject() {
return SynchronizedDeque.synchronizedDeque(new LinkedList<E>());
}
@Override
public String getCompatibilityVersion() {
return "4.5";
}
@Ignore("Run once")
public void testCreate() throws Exception {
Deque<E> deque = makeObject();
writeExternalFormToDisk((java.io.Serializable) deque, "src/test/resources/data/test/SynchronizedDeque.emptyCollection.version4.5.obj");
deque = makeFullCollection();
writeExternalFormToDisk((java.io.Serializable) deque, "src/test/resources/data/test/SynchronizedDeque.fullCollection.version4.5.obj");
}
}

View File

@ -24,7 +24,12 @@ import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
/**
* Extension of {@link AbstractDequeTest} for exercising the
* {@link TransformedDeque} implementation.
*
* @since 4.5
*/
public class TransformedDequeTest<E> extends AbstractDequeTest<E> {
/**