mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
classlib: inheritDeque from SequencedCollection, fix ArrayDeque (#765)
Second part of JEP-431
This commit is contained in:
parent
ada85b4c07
commit
0ef08a01e7
|
@ -16,9 +16,10 @@
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import org.teavm.classlib.java.lang.*;
|
import org.teavm.classlib.java.io.TSerializable;
|
||||||
|
import org.teavm.classlib.java.lang.TCloneable;
|
||||||
|
|
||||||
public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E> {
|
public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>, TCloneable, TSerializable {
|
||||||
private int version;
|
private int version;
|
||||||
private Object[] array;
|
private Object[] array;
|
||||||
private int head;
|
private int head;
|
||||||
|
@ -38,8 +39,8 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
} else {
|
} else {
|
||||||
array = new Object[c.size() + 1];
|
array = new Object[c.size() + 1];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (TIterator<? extends E> iter = c.iterator(); iter.hasNext();) {
|
for (var it = c.iterator(); it.hasNext();) {
|
||||||
array[index++] = iter.next();
|
array[index++] = it.next();
|
||||||
}
|
}
|
||||||
tail = array.length - 1;
|
tail = array.length - 1;
|
||||||
}
|
}
|
||||||
|
@ -47,28 +48,19 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFirst(E e) {
|
public void addFirst(E e) {
|
||||||
if (e == null) {
|
TObjects.requireNonNull(e);
|
||||||
throw new TNullPointerException();
|
|
||||||
}
|
|
||||||
ensureCapacity(size() + 1);
|
ensureCapacity(size() + 1);
|
||||||
--head;
|
head = modDec(head, array.length);
|
||||||
if (head < 0) {
|
|
||||||
head += array.length;
|
|
||||||
}
|
|
||||||
array[head] = e;
|
array[head] = e;
|
||||||
++version;
|
++version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addLast(E e) {
|
public void addLast(E e) {
|
||||||
if (e == null) {
|
TObjects.requireNonNull(e);
|
||||||
throw new TNullPointerException();
|
|
||||||
}
|
|
||||||
ensureCapacity(size() + 1);
|
ensureCapacity(size() + 1);
|
||||||
array[tail++] = e;
|
array[tail] = e;
|
||||||
if (tail >= array.length) {
|
tail = modInc(tail, array.length);
|
||||||
tail = 0;
|
|
||||||
}
|
|
||||||
++version;
|
++version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,10 +102,7 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
E result = (E) array[head];
|
E result = (E) array[head];
|
||||||
array[head] = null;
|
array[head] = null;
|
||||||
head++;
|
head = modInc(head, array.length);
|
||||||
if (head >= array.length) {
|
|
||||||
head = 0;
|
|
||||||
}
|
|
||||||
++version;
|
++version;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -123,10 +112,7 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
if (head == tail) {
|
if (head == tail) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
--tail;
|
tail = modDec(tail, array.length);
|
||||||
if (tail < 0) {
|
|
||||||
tail = array.length - 1;
|
|
||||||
}
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
E result = (E) array[tail];
|
E result = (E) array[tail];
|
||||||
array[tail] = null;
|
array[tail] = null;
|
||||||
|
@ -161,7 +147,7 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public E peekLast() {
|
public E peekLast() {
|
||||||
return !isEmpty() ? (E) array[tail > 0 ? tail - 1 : array.length - 1] : null;
|
return !isEmpty() ? (E) array[modDec(tail, array.length)] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -169,9 +155,9 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (TIterator<E> iter = iterator(); iter.hasNext();) {
|
for (var it = iterator(); it.hasNext();) {
|
||||||
if (iter.next().equals(o)) {
|
if (it.next().equals(o)) {
|
||||||
iter.remove();
|
it.remove();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,9 +169,9 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (TIterator<E> iter = descendingIterator(); iter.hasNext();) {
|
for (var it = descendingIterator(); it.hasNext();) {
|
||||||
if (iter.next().equals(o)) {
|
if (it.next().equals(o)) {
|
||||||
iter.remove();
|
it.remove();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,68 +229,85 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
return head == tail;
|
return head == tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeAt(int index) {
|
private boolean removeAt(int index) {
|
||||||
if (head < tail) {
|
if (head < tail) {
|
||||||
if (tail - index < index - head) {
|
if (tail - index < index - head) {
|
||||||
for (int i = index + 1; i < tail; ++i) {
|
for (int i = index + 1; i < tail; ++i) {
|
||||||
array[i - 1] = array[i];
|
array[i - 1] = array[i];
|
||||||
}
|
}
|
||||||
array[--tail] = null;
|
array[--tail] = null;
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
for (int i = index - 1; i >= head; --i) {
|
for (int i = index - 1; i >= head; --i) {
|
||||||
array[i + 1] = array[i];
|
array[i + 1] = array[i];
|
||||||
}
|
}
|
||||||
array[head++] = null;
|
array[head++] = null;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (index >= head) {
|
if (index >= head) {
|
||||||
for (int i = index - 1; i >= head; --i) {
|
for (int i = index - 1; i >= head; --i) {
|
||||||
array[i + 1] = array[i];
|
array[i + 1] = array[i];
|
||||||
}
|
}
|
||||||
array[head++] = null;
|
array[head] = null;
|
||||||
if (head >= array.length) {
|
head = modInc(head, array.length);
|
||||||
head = 0;
|
return false;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (int i = index + 1; i < tail; ++i) {
|
for (int i = index + 1; i < tail; ++i) {
|
||||||
array[i - 1] = array[i];
|
array[i - 1] = array[i];
|
||||||
}
|
}
|
||||||
if (--tail < 0) {
|
tail = modDec(tail, array.length);
|
||||||
tail += array.length;
|
|
||||||
}
|
|
||||||
array[tail] = null;
|
array[tail] = null;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int modInc(int i, int mod) {
|
||||||
|
return ++i == mod ? 0 : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int modDec(int i, int mod) {
|
||||||
|
return --i == -1 ? mod - 1 : i;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TIterator<E> iterator() {
|
public TIterator<E> iterator() {
|
||||||
return new TIterator<E>() {
|
return new TIterator<>() {
|
||||||
private int refVersion = version;
|
private int refVersion = version;
|
||||||
private int index = head;
|
private int index = head;
|
||||||
private int lastIndex = -1;
|
private int lastIndex = -1;
|
||||||
private boolean wrapped = head <= tail;
|
private int left = size();
|
||||||
@Override public boolean hasNext() {
|
|
||||||
return !wrapped || index < tail;
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return left > 0;
|
||||||
}
|
}
|
||||||
@Override public E next() {
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
|
if (--left < 0) {
|
||||||
|
throw new TNoSuchElementException();
|
||||||
|
}
|
||||||
if (version > refVersion) {
|
if (version > refVersion) {
|
||||||
throw new TConcurrentModificationException();
|
throw new TConcurrentModificationException();
|
||||||
}
|
}
|
||||||
lastIndex = index;
|
lastIndex = index;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
E result = (E) array[index++];
|
E result = (E) array[index];
|
||||||
if (index >= array.length) {
|
index = modInc(index, array.length);
|
||||||
index = 0;
|
|
||||||
wrapped = true;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@Override public void remove() {
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
if (lastIndex < 0) {
|
if (lastIndex < 0) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
removeAt(lastIndex);
|
boolean toLeft = removeAt(lastIndex);
|
||||||
|
if (toLeft) {
|
||||||
|
index = modInc(index, array.length);
|
||||||
|
}
|
||||||
lastIndex = -1;
|
lastIndex = -1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -312,30 +315,41 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TIterator<E> descendingIterator() {
|
public TIterator<E> descendingIterator() {
|
||||||
return new TIterator<E>() {
|
return new TIterator<>() {
|
||||||
private int refVersion = version;
|
private int refVersion = version;
|
||||||
private int index = tail;
|
private int index = tail;
|
||||||
private int lastIndex = -1;
|
private int lastIndex = -1;
|
||||||
private boolean wrapped = head <= tail;
|
private int left = size();
|
||||||
@Override public boolean hasNext() {
|
|
||||||
return !wrapped || index > head;
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return left > 0;
|
||||||
}
|
}
|
||||||
@Override public E next() {
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
|
if (--left < 0) {
|
||||||
|
throw new TNoSuchElementException();
|
||||||
|
}
|
||||||
if (version > refVersion) {
|
if (version > refVersion) {
|
||||||
throw new TConcurrentModificationException();
|
throw new TConcurrentModificationException();
|
||||||
}
|
}
|
||||||
--index;
|
index = modDec(index, array.length);
|
||||||
if (index < 0) {
|
|
||||||
index = array.length - 1;
|
|
||||||
wrapped = true;
|
|
||||||
}
|
|
||||||
lastIndex = index;
|
lastIndex = index;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
E result = (E) array[index];
|
E result = (E) array[index];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@Override public void remove() {
|
|
||||||
removeAt(lastIndex);
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if (lastIndex < 0) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
boolean toLeft = removeAt(lastIndex);
|
||||||
|
if (!toLeft) {
|
||||||
|
index = modInc(index, array.length);
|
||||||
|
}
|
||||||
lastIndex = -1;
|
lastIndex = -1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -345,9 +359,9 @@ public class TArrayDeque<E> extends TAbstractCollection<E> implements TDeque<E>
|
||||||
if (capacity < array.length) {
|
if (capacity < array.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int newArraySize = TMath.max(array.length * 2, capacity * 3 / 2 + 1);
|
int newArraySize = Math.max(array.length * 2, capacity * 3 / 2 + 1);
|
||||||
if (newArraySize < 1) {
|
if (newArraySize < 1) {
|
||||||
newArraySize = TInteger.MAX_VALUE;
|
newArraySize = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
Object[] newArray = new Object[newArraySize];
|
Object[] newArray = new Object[newArraySize];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
|
@ -16,31 +16,18 @@
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
* @param <E>
|
* @param <E>
|
||||||
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public interface TDeque<E> extends TQueue<E> {
|
public interface TDeque<E> extends TQueue<E>, TSequencedCollection<E> {
|
||||||
void addFirst(E e);
|
|
||||||
|
|
||||||
void addLast(E e);
|
|
||||||
|
|
||||||
boolean offerFirst(E e);
|
boolean offerFirst(E e);
|
||||||
|
|
||||||
boolean offerLast(E e);
|
boolean offerLast(E e);
|
||||||
|
|
||||||
E removeFirst();
|
|
||||||
|
|
||||||
E removeLast();
|
|
||||||
|
|
||||||
E pollFirst();
|
E pollFirst();
|
||||||
|
|
||||||
E pollLast();
|
E pollLast();
|
||||||
|
|
||||||
E getFirst();
|
|
||||||
|
|
||||||
E getLast();
|
|
||||||
|
|
||||||
E peekFirst();
|
E peekFirst();
|
||||||
|
|
||||||
E peekLast();
|
E peekLast();
|
||||||
|
@ -54,4 +41,9 @@ public interface TDeque<E> extends TQueue<E> {
|
||||||
E pop();
|
E pop();
|
||||||
|
|
||||||
TIterator<E> descendingIterator();
|
TIterator<E> descendingIterator();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default TDeque<E> reversed() {
|
||||||
|
return new TReversedDeque<>(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 ihromant.
|
||||||
|
*
|
||||||
|
* Licensed 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.teavm.classlib.java.util;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
|
||||||
|
class TReversedDeque<E> implements TDeque<E> {
|
||||||
|
private final TDeque<E> base;
|
||||||
|
|
||||||
|
TReversedDeque(TDeque<E> base) {
|
||||||
|
this.base = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TDeque<E> reversed() {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TIterator<E> iterator() {
|
||||||
|
return base.descendingIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return base.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return base.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return base.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] toArray() {
|
||||||
|
Object[] arr = new Object[size()];
|
||||||
|
int i = 0;
|
||||||
|
for (var it = base.descendingIterator(); it.hasNext();) {
|
||||||
|
arr[i++] = it.next();
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <T> T[] toArray(T[] a) {
|
||||||
|
int size = size();
|
||||||
|
if (a.length < size) {
|
||||||
|
a = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
|
||||||
|
} else {
|
||||||
|
for (int i = size; i < a.length; ++i) {
|
||||||
|
a[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
for (var it = base.descendingIterator(); it.hasNext();) {
|
||||||
|
a[i++] = (T) it.next();
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(E e) {
|
||||||
|
base.addFirst(e);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFirst(E e) {
|
||||||
|
base.addLast(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLast(E e) {
|
||||||
|
base.addFirst(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
for (var it = base.descendingIterator(); it.hasNext();) {
|
||||||
|
E e = it.next();
|
||||||
|
if (TObjects.equals(e, o)) {
|
||||||
|
it.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(TCollection<?> c) {
|
||||||
|
return base.contains(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(TCollection<? extends E> c) {
|
||||||
|
boolean changed = false;
|
||||||
|
for (var it = c.iterator(); it.hasNext();) {
|
||||||
|
addFirst(it.next());
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(TCollection<?> c) {
|
||||||
|
boolean changed = false;
|
||||||
|
for (var it = base.descendingIterator(); it.hasNext();) {
|
||||||
|
E e = it.next();
|
||||||
|
if (c.contains(e)) {
|
||||||
|
it.remove();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(TCollection<?> c) {
|
||||||
|
boolean changed = false;
|
||||||
|
for (var it = base.descendingIterator(); it.hasNext();) {
|
||||||
|
E e = it.next();
|
||||||
|
if (!c.contains(e)) {
|
||||||
|
it.remove();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
base.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean offerFirst(E e) {
|
||||||
|
return base.offerLast(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean offerLast(E e) {
|
||||||
|
return base.offerFirst(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E pollFirst() {
|
||||||
|
return base.pollLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E pollLast() {
|
||||||
|
return base.pollFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E peekFirst() {
|
||||||
|
return base.peekLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E peekLast() {
|
||||||
|
return base.peekFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeFirstOccurrence(Object o) {
|
||||||
|
return base.removeLastOccurrence(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeLastOccurrence(Object o) {
|
||||||
|
return base.removeFirstOccurrence(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void push(E e) {
|
||||||
|
base.addLast(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E pop() {
|
||||||
|
return base.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TIterator<E> descendingIterator() {
|
||||||
|
return base.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean offer(E e) {
|
||||||
|
return base.offerFirst(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E remove() {
|
||||||
|
return base.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E removeFirst() {
|
||||||
|
return base.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E removeLast() {
|
||||||
|
return base.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E poll() {
|
||||||
|
return base.pollLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E element() {
|
||||||
|
return base.getLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getFirst() {
|
||||||
|
return base.getLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getLast() {
|
||||||
|
return base.getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E peek() {
|
||||||
|
return base.peekLast();
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,12 +15,16 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import org.junit.Assert;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.teavm.junit.TeaVMTestRunner;
|
import org.teavm.junit.TeaVMTestRunner;
|
||||||
|
@ -137,19 +141,19 @@ public class ArrayDequeTest {
|
||||||
Object object2 = new Object();
|
Object object2 = new Object();
|
||||||
Object object3 = new Object();
|
Object object3 = new Object();
|
||||||
arrayDeque.add(object1);
|
arrayDeque.add(object1);
|
||||||
Assert.assertTrue(arrayDeque.size() == 1);
|
assertEquals(1, arrayDeque.size());
|
||||||
arrayDeque.remove(object1);
|
arrayDeque.remove(object1);
|
||||||
Assert.assertTrue(arrayDeque.size() == 0);
|
assertEquals(0, arrayDeque.size());
|
||||||
arrayDeque.add(object1);
|
arrayDeque.add(object1);
|
||||||
arrayDeque.add(object2);
|
arrayDeque.add(object2);
|
||||||
arrayDeque.add(object3);
|
arrayDeque.add(object3);
|
||||||
Assert.assertTrue(arrayDeque.size() == 3);
|
assertEquals(3, arrayDeque.size());
|
||||||
arrayDeque.remove(object1);
|
arrayDeque.remove(object1);
|
||||||
arrayDeque.remove(object2);
|
arrayDeque.remove(object2);
|
||||||
arrayDeque.remove(object3);
|
arrayDeque.remove(object3);
|
||||||
Assert.assertTrue(arrayDeque.size() == 0);
|
assertEquals(0, arrayDeque.size());
|
||||||
arrayDeque.remove(object1);
|
arrayDeque.remove(object1);
|
||||||
Assert.assertTrue(arrayDeque.size() == 0);
|
assertEquals(0, arrayDeque.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -162,9 +166,9 @@ public class ArrayDequeTest {
|
||||||
arrayDeque1.add(object2);
|
arrayDeque1.add(object2);
|
||||||
arrayDeque1.add(object3);
|
arrayDeque1.add(object3);
|
||||||
arrayDeque1.removeFirst();
|
arrayDeque1.removeFirst();
|
||||||
Assert.assertTrue(arrayDeque1.size() == 2);
|
assertEquals(2, arrayDeque1.size());
|
||||||
Assert.assertTrue(arrayDeque1.contains(object2));
|
assertTrue(arrayDeque1.contains(object2));
|
||||||
Assert.assertTrue(arrayDeque1.contains(object3));
|
assertTrue(arrayDeque1.contains(object3));
|
||||||
|
|
||||||
ArrayDeque<Object> arrayDeque2 = new ArrayDeque<>();
|
ArrayDeque<Object> arrayDeque2 = new ArrayDeque<>();
|
||||||
arrayDeque2.add(object1);
|
arrayDeque2.add(object1);
|
||||||
|
@ -172,8 +176,8 @@ public class ArrayDequeTest {
|
||||||
arrayDeque2.add(object3);
|
arrayDeque2.add(object3);
|
||||||
arrayDeque2.remove(object1);
|
arrayDeque2.remove(object1);
|
||||||
arrayDeque2.removeFirst();
|
arrayDeque2.removeFirst();
|
||||||
Assert.assertTrue(arrayDeque2.size() == 1);
|
assertEquals(1, arrayDeque2.size());
|
||||||
Assert.assertTrue(arrayDeque2.contains(object3));
|
assertTrue(arrayDeque2.contains(object3));
|
||||||
|
|
||||||
ArrayDeque<Object> arrayDeque3 = new ArrayDeque<>();
|
ArrayDeque<Object> arrayDeque3 = new ArrayDeque<>();
|
||||||
arrayDeque3.add(object1);
|
arrayDeque3.add(object1);
|
||||||
|
@ -181,8 +185,8 @@ public class ArrayDequeTest {
|
||||||
arrayDeque3.add(object3);
|
arrayDeque3.add(object3);
|
||||||
arrayDeque3.remove(object2);
|
arrayDeque3.remove(object2);
|
||||||
arrayDeque3.removeFirst();
|
arrayDeque3.removeFirst();
|
||||||
Assert.assertTrue(arrayDeque3.size() == 1);
|
assertEquals(1, arrayDeque3.size());
|
||||||
Assert.assertTrue(arrayDeque3.contains(object3));
|
assertTrue(arrayDeque3.contains(object3));
|
||||||
|
|
||||||
ArrayDeque<Object> arrayDeque4 = new ArrayDeque<>();
|
ArrayDeque<Object> arrayDeque4 = new ArrayDeque<>();
|
||||||
arrayDeque4.add(object1);
|
arrayDeque4.add(object1);
|
||||||
|
@ -190,8 +194,8 @@ public class ArrayDequeTest {
|
||||||
arrayDeque4.add(object3);
|
arrayDeque4.add(object3);
|
||||||
arrayDeque4.remove(object3);
|
arrayDeque4.remove(object3);
|
||||||
arrayDeque4.removeFirst();
|
arrayDeque4.removeFirst();
|
||||||
Assert.assertTrue(arrayDeque4.size() == 1);
|
assertEquals(1, arrayDeque4.size());
|
||||||
Assert.assertTrue(arrayDeque4.contains(object2));
|
assertTrue(arrayDeque4.contains(object2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -204,9 +208,9 @@ public class ArrayDequeTest {
|
||||||
arrayDeque1.add(object2);
|
arrayDeque1.add(object2);
|
||||||
arrayDeque1.add(object3);
|
arrayDeque1.add(object3);
|
||||||
arrayDeque1.removeLast();
|
arrayDeque1.removeLast();
|
||||||
Assert.assertTrue(arrayDeque1.size() == 2);
|
assertEquals(2, arrayDeque1.size());
|
||||||
Assert.assertTrue(arrayDeque1.contains(object1));
|
assertTrue(arrayDeque1.contains(object1));
|
||||||
Assert.assertTrue(arrayDeque1.contains(object2));
|
assertTrue(arrayDeque1.contains(object2));
|
||||||
|
|
||||||
ArrayDeque<Object> arrayDeque2 = new ArrayDeque<>();
|
ArrayDeque<Object> arrayDeque2 = new ArrayDeque<>();
|
||||||
arrayDeque2.add(object1);
|
arrayDeque2.add(object1);
|
||||||
|
@ -214,8 +218,8 @@ public class ArrayDequeTest {
|
||||||
arrayDeque2.add(object3);
|
arrayDeque2.add(object3);
|
||||||
arrayDeque2.remove(object3);
|
arrayDeque2.remove(object3);
|
||||||
arrayDeque2.removeLast();
|
arrayDeque2.removeLast();
|
||||||
Assert.assertTrue(arrayDeque2.size() == 1);
|
assertEquals(1, arrayDeque2.size());
|
||||||
Assert.assertTrue(arrayDeque2.contains(object1));
|
assertTrue(arrayDeque2.contains(object1));
|
||||||
|
|
||||||
ArrayDeque<Object> arrayDeque3 = new ArrayDeque<>();
|
ArrayDeque<Object> arrayDeque3 = new ArrayDeque<>();
|
||||||
arrayDeque3.add(object1);
|
arrayDeque3.add(object1);
|
||||||
|
@ -223,8 +227,8 @@ public class ArrayDequeTest {
|
||||||
arrayDeque3.add(object3);
|
arrayDeque3.add(object3);
|
||||||
arrayDeque3.remove(object2);
|
arrayDeque3.remove(object2);
|
||||||
arrayDeque3.removeLast();
|
arrayDeque3.removeLast();
|
||||||
Assert.assertTrue(arrayDeque3.size() == 1);
|
assertEquals(1, arrayDeque3.size());
|
||||||
Assert.assertTrue(arrayDeque3.contains(object1));
|
assertTrue(arrayDeque3.contains(object1));
|
||||||
|
|
||||||
ArrayDeque<Object> arrayDeque4 = new ArrayDeque<>();
|
ArrayDeque<Object> arrayDeque4 = new ArrayDeque<>();
|
||||||
arrayDeque4.add(object1);
|
arrayDeque4.add(object1);
|
||||||
|
@ -232,8 +236,8 @@ public class ArrayDequeTest {
|
||||||
arrayDeque4.add(object3);
|
arrayDeque4.add(object3);
|
||||||
arrayDeque4.remove(object3);
|
arrayDeque4.remove(object3);
|
||||||
arrayDeque4.removeLast();
|
arrayDeque4.removeLast();
|
||||||
Assert.assertTrue(arrayDeque4.size() == 1);
|
assertEquals(1, arrayDeque4.size());
|
||||||
Assert.assertTrue(arrayDeque4.contains(object1));
|
assertTrue(arrayDeque4.contains(object1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -254,4 +258,115 @@ public class ArrayDequeTest {
|
||||||
arrayDeque.removeLast();
|
arrayDeque.removeLast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSequencedCollectionReadOnly() {
|
||||||
|
Deque<String> deque = new ArrayDeque<>(List.of("0", "1", "2", "3", "4", "5", "6"));
|
||||||
|
Deque<String> reversed = deque.reversed();
|
||||||
|
Iterator<String> it = reversed.iterator();
|
||||||
|
assertEquals("6", it.next());
|
||||||
|
assertEquals("5", it.next());
|
||||||
|
assertEquals("6", reversed.getFirst());
|
||||||
|
assertEquals("0", reversed.getLast());
|
||||||
|
assertEquals("6", reversed.peek());
|
||||||
|
assertEquals("6", reversed.peekFirst());
|
||||||
|
assertEquals("0", reversed.peekLast());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSequencedCollectionMutations() {
|
||||||
|
Deque<String> deque = new ArrayDeque<>(List.of("a", "b", "c", "d"));
|
||||||
|
assertEquals("a", deque.removeFirst());
|
||||||
|
assertEquals("d", deque.removeLast());
|
||||||
|
deque.addFirst("u");
|
||||||
|
deque.addLast("e");
|
||||||
|
assertArrayEquals(new String[] { "u", "b", "c", "e" }, deque.toArray());
|
||||||
|
deque = new ArrayDeque<>(List.of("a", "b", "c", "d")).reversed();
|
||||||
|
assertEquals("d", deque.removeFirst());
|
||||||
|
assertEquals("a", deque.removeLast());
|
||||||
|
deque.addFirst("u");
|
||||||
|
deque.addLast("e");
|
||||||
|
assertEquals("u", deque.remove());
|
||||||
|
deque.add("f");
|
||||||
|
assertArrayEquals(new String[] { "c", "b", "e", "f" }, deque.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSequencedCollectionIterator() {
|
||||||
|
Deque<String> deque = new ArrayDeque<>(List.of("a", "b", "c", "d"));
|
||||||
|
deque.addLast("e");
|
||||||
|
deque.addLast("f");
|
||||||
|
Iterator<String> it = deque.iterator();
|
||||||
|
assertEquals("a", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertEquals("b", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertEquals("c", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertEquals("d", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertEquals("e", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertEquals("f", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertTrue(deque.isEmpty());
|
||||||
|
try {
|
||||||
|
it.next();
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
deque = new ArrayDeque<>(List.of("a", "b", "c", "d")).reversed();
|
||||||
|
it = deque.iterator();
|
||||||
|
assertEquals("d", it.next());
|
||||||
|
assertEquals("c", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertArrayEquals(new String[] { "d", "b", "a" }, deque.toArray());
|
||||||
|
deque = new ArrayDeque<>(List.of("a", "b", "c", "d")).reversed();
|
||||||
|
it = deque.iterator();
|
||||||
|
assertEquals("d", it.next());
|
||||||
|
assertEquals("c", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertEquals("b", it.next());
|
||||||
|
it.remove();
|
||||||
|
assertEquals("a", it.next());
|
||||||
|
try {
|
||||||
|
it.next();
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
assertArrayEquals(new String[] { "d", "a" }, deque.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sequenceCollectionMethodsOnEmpty() {
|
||||||
|
var empty = new ArrayDeque<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
empty.getFirst();
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
empty.getLast();
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
empty.removeFirst();
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
empty.removeLast();
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user