Add some files for Deque
This commit is contained in:
parent
138898ce62
commit
d682042aaa
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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 < 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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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> {
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue