mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-03 13:54:10 -08:00
classlib: add SequencedCollection interface, inherited List from it (#759)
(initial part of JEP-431)
This commit is contained in:
parent
57ca715195
commit
55426b25cf
classlib/src/main/java/org/teavm/classlib/java/util
TAbstractCollection.javaTAbstractList.javaTArrayList.javaTLinkedList.javaTList.javaTReversedList.javaTSequencedCollection.java
tests/src/test/java/org/teavm/classlib/java/util
|
@ -32,7 +32,7 @@ public abstract class TAbstractCollection<E> extends TObject implements TCollect
|
|||
public boolean contains(Object o) {
|
||||
for (TIterator<E> iter = iterator(); iter.hasNext();) {
|
||||
E e = iter.next();
|
||||
if (e == null ? o == null : e.equals(o)) {
|
||||
if (TObjects.equals(e, o)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public abstract class TAbstractCollection<E> extends TObject implements TCollect
|
|||
public boolean remove(Object o) {
|
||||
for (TIterator<E> iter = iterator(); iter.hasNext();) {
|
||||
E e = iter.next();
|
||||
if (e == null ? o == null : e.equals(o)) {
|
||||
if (TObjects.equals(e, o)) {
|
||||
iter.remove();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public abstract class TAbstractList<E> extends TAbstractCollection<E> implements
|
|||
|
||||
@Override
|
||||
public TIterator<E> iterator() {
|
||||
return new TIterator<E>() {
|
||||
return new TIterator<>() {
|
||||
private int index;
|
||||
private int modCount = TAbstractList.this.modCount;
|
||||
private int size = size();
|
||||
|
|
|
@ -64,6 +64,16 @@ public class TArrayList<E> extends TAbstractList<E> implements TCloneable, TSeri
|
|||
return array[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFirst() {
|
||||
return get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getLast() {
|
||||
return get(size - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
|
@ -102,6 +112,26 @@ public class TArrayList<E> extends TAbstractList<E> implements TCloneable, TSeri
|
|||
++modCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFirst(E element) {
|
||||
add(0, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLast(E element) {
|
||||
add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeFirst() {
|
||||
return remove(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeLast() {
|
||||
return remove(size - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
checkIndex(index);
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
*/
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import org.teavm.classlib.java.util.function.TUnaryOperator;
|
||||
import org.teavm.classlib.java.util.stream.TStream;
|
||||
|
||||
public class TLinkedList<E> extends TAbstractSequentialList<E> implements TDeque<E> {
|
||||
static class Entry<E> {
|
||||
E item;
|
||||
|
@ -275,6 +281,11 @@ public class TLinkedList<E> extends TAbstractSequentialList<E> implements TDeque
|
|||
return new DescendingIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TLinkedList<E> reversed() {
|
||||
return new ReversedLinkedList<>(this);
|
||||
}
|
||||
|
||||
private void removeEntry(Entry<E> entry) {
|
||||
if (entry.previous != null) {
|
||||
entry.previous.next = entry.next;
|
||||
|
@ -441,4 +452,390 @@ public class TLinkedList<E> extends TAbstractSequentialList<E> implements TDeque
|
|||
currentEntry = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReversedLinkedList<E> extends TLinkedList<E> {
|
||||
private final TLinkedList<E> list;
|
||||
private final TReversedList<E> reversed;
|
||||
|
||||
private ReversedLinkedList(TLinkedList<E> list) {
|
||||
this.list = list;
|
||||
this.reversed = new TReversedList<>(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return reversed.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(TCollection<?> c) {
|
||||
return reversed.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(TCollection<?> c) {
|
||||
return reversed.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(TCollection<?> c) {
|
||||
return reversed.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TStream<E> stream() {
|
||||
return reversed.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeIf(Predicate<? super E> filter) {
|
||||
return list.removeIf(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(IntFunction<T[]> generator) {
|
||||
return reversed.toArray(generator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
reversed.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TIterator<E> iterator() {
|
||||
return list.descendingIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return reversed.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return reversed.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TList<E> subList(int fromIndex, int toIndex) {
|
||||
return reversed.subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TListIterator<E> listIterator() {
|
||||
TListIterator<E> lit = list.listIterator(list.size());
|
||||
return new TListIterator<>() {
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return lit.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E previous() {
|
||||
return lit.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return list.size() - lit.previousIndex() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return list.size() - lit.nextIndex() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(E e) {
|
||||
lit.set(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(E e) {
|
||||
lit.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return lit.hasPrevious();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
return lit.previous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
lit.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(TComparator<? super E> c) {
|
||||
reversed.sort(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(TUnaryOperator<E> operator) {
|
||||
list.replaceAll(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TLinkedList<E> reversed() {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TSpliterator<E> spliterator() {
|
||||
return reversed.spliterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
return reversed.toArray(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return reversed.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TIterator<E> descendingIterator() {
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TListIterator<E> listIterator(int index) {
|
||||
TListIterator<E> lit = list.listIterator(list.size() - index);
|
||||
return new TListIterator<>() {
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return lit.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E previous() {
|
||||
return lit.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return list.size() - lit.previousIndex() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return list.size() - lit.nextIndex() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(E e) {
|
||||
lit.set(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(E e) {
|
||||
lit.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return lit.hasPrevious();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
return lit.previous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
lit.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLastOccurrence(Object o) {
|
||||
return list.removeFirstOccurrence(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFirstOccurrence(Object o) {
|
||||
return list.removeLastOccurrence(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pop() {
|
||||
return list.removeLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(E e) {
|
||||
list.addLast(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pollLast() {
|
||||
return list.pollFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pollFirst() {
|
||||
return list.pollLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peekLast() {
|
||||
return list.peekFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peekFirst() {
|
||||
return list.peekLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offerLast(E e) {
|
||||
return list.offerFirst(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offerFirst(E e) {
|
||||
return list.offerLast(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offer(E e) {
|
||||
return list.offerLast(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove() {
|
||||
return list.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E poll() {
|
||||
return list.pollLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E element() {
|
||||
if (list.lastEntry == null) {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
return list.lastEntry.item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peek() {
|
||||
return list.lastEntry != null ? list.lastEntry.item : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
return list.size() - list.indexOf(o) - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
return list.size() - list.lastIndexOf(o) - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
return reversed.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
reversed.add(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
return reversed.set(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
return reversed.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
list.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, TCollection<? extends E> c) {
|
||||
return reversed.addAll(index, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(TCollection<? extends E> c) {
|
||||
return reversed.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return list.removeLastOccurrence(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
list.addLast(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return list.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLast(E e) {
|
||||
list.addFirst(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFirst(E e) {
|
||||
list.addLast(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeLast() {
|
||||
return list.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeFirst() {
|
||||
return list.removeLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getLast() {
|
||||
return list.getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFirst() {
|
||||
return list.getLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ package org.teavm.classlib.java.util;
|
|||
import java.util.Objects;
|
||||
import org.teavm.classlib.java.util.function.TUnaryOperator;
|
||||
|
||||
public interface TList<E> extends TCollection<E> {
|
||||
public interface TList<E> extends TSequencedCollection<E> {
|
||||
boolean addAll(int index, TCollection<? extends E> c);
|
||||
|
||||
E get(int index);
|
||||
|
@ -50,6 +50,54 @@ public interface TList<E> extends TCollection<E> {
|
|||
TCollections.sort(this, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void addFirst(E e) {
|
||||
add(0, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void addLast(E e) {
|
||||
add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
default E getFirst() {
|
||||
if (isEmpty()) {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
return get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
default E getLast() {
|
||||
if (isEmpty()) {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
return get(this.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
default E removeFirst() {
|
||||
if (isEmpty()) {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
return remove(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
default E removeLast() {
|
||||
if (isEmpty()) {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
return remove(this.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
default TList<E> reversed() {
|
||||
return this instanceof TRandomAccess ? new TReversedList.RandomAccess<>(this)
|
||||
: new TReversedList<>(this);
|
||||
}
|
||||
|
||||
static <E> TList<E> of() {
|
||||
return TCollections.emptyList();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
class TReversedList<E> extends TAbstractList<E> {
|
||||
private final TList<E> base;
|
||||
|
||||
TReversedList(TList<E> base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
return base.get(size() - index - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return base.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
return base.set(size() - index - 1, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
base.add(size() - index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
return base.remove(size() - index - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFirst(E element) {
|
||||
base.addLast(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLast(E element) {
|
||||
base.addFirst(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeFirst() {
|
||||
return base.remove(size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeLast() {
|
||||
return base.remove(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFirst() {
|
||||
return base.getLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getLast() {
|
||||
return base.getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TIterator<E> iterator() {
|
||||
TListIterator<E> lit = base.listIterator(size());
|
||||
return new TIterator<>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return lit.hasPrevious();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
return lit.previous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
lit.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
base.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return base.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TList<E> reversed() {
|
||||
return base;
|
||||
}
|
||||
|
||||
static class RandomAccess<E> extends TReversedList<E> implements TRandomAccess {
|
||||
RandomAccess(TList<E> base) {
|
||||
super(base);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public interface TSequencedCollection<E> extends TCollection<E> {
|
||||
|
||||
TSequencedCollection<E> reversed();
|
||||
|
||||
default void addFirst(E e) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
default void addLast(E e) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
default E getFirst() {
|
||||
return this.iterator().next();
|
||||
}
|
||||
|
||||
default E getLast() {
|
||||
return this.reversed().iterator().next();
|
||||
}
|
||||
|
||||
default E removeFirst() {
|
||||
var it = this.iterator();
|
||||
E e = it.next();
|
||||
it.remove();
|
||||
return e;
|
||||
}
|
||||
|
||||
default E removeLast() {
|
||||
var it = this.reversed().iterator();
|
||||
E e = it.next();
|
||||
it.remove();
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,19 +16,26 @@
|
|||
package org.teavm.classlib.java.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.teavm.junit.TeaVMTestRunner;
|
||||
import org.teavm.junit.WholeClassCompilation;
|
||||
|
||||
@RunWith(TeaVMTestRunner.class)
|
||||
@WholeClassCompilation
|
||||
public class ArrayListTest {
|
||||
@Test
|
||||
public void elementsAdded() {
|
||||
|
@ -208,4 +215,79 @@ public class ArrayListTest {
|
|||
assertEquals(new LinkedList<>(Arrays.asList(1, 3, null, 2)), new ArrayList<>(Arrays.asList(1, 3, null, 2)));
|
||||
assertNotEquals(new ArrayList<>(Arrays.asList(1, 3, 2)), new ArrayList<>(Arrays.asList(1, 3, null, 2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequencedCollectionReadOnly() {
|
||||
List<String> list = new ArrayList<>(List.of("0", "1", "2", "3", "4", "5", "6"));
|
||||
List<String> reversed = list.reversed();
|
||||
assertEquals("1", reversed.get(5));
|
||||
Iterator<String> it = reversed.iterator();
|
||||
assertEquals("6", it.next());
|
||||
assertEquals("5", it.next());
|
||||
assertEquals("6", reversed.getFirst());
|
||||
assertEquals("0", reversed.getLast());
|
||||
ListIterator<String> lit = reversed.listIterator();
|
||||
assertFalse(lit.hasPrevious());
|
||||
assertTrue(lit.hasNext());
|
||||
assertEquals("6", lit.next());
|
||||
assertEquals("5", lit.next());
|
||||
assertEquals("5", lit.previous());
|
||||
lit = reversed.listIterator(2);
|
||||
assertEquals("4", lit.next());
|
||||
lit.previous();
|
||||
assertEquals("5", lit.previous());
|
||||
assertSame(list, reversed.reversed());
|
||||
List<String> subList = reversed.subList(3, 5);
|
||||
assertEquals("2", subList.getLast());
|
||||
assertEquals("3", subList.listIterator().next());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
subList.forEach(sb::append);
|
||||
assertEquals("32", sb.toString());
|
||||
List<Integer> duplicates = new ArrayList<>(List.of(0, 1, 2, 3, 2, 1, 0, 0)).reversed();
|
||||
assertEquals(2, duplicates.indexOf(1));
|
||||
assertEquals(6, duplicates.lastIndexOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequencedCollectionMutations() {
|
||||
List<String> list = new ArrayList<>(List.of("a", "b", "c", "d"));
|
||||
assertEquals("a", list.removeFirst());
|
||||
assertEquals("d", list.removeLast());
|
||||
list.addFirst("u");
|
||||
list.addLast("e");
|
||||
assertEquals(List.of("u", "b", "c", "e"), list);
|
||||
list = new ArrayList<>(List.of("a", "b", "c", "d")).reversed();
|
||||
assertEquals("d", list.removeFirst());
|
||||
assertEquals("a", list.removeLast());
|
||||
list.addFirst("u");
|
||||
list.addLast("e");
|
||||
assertEquals("c", list.remove(1));
|
||||
list.add(2, "f");
|
||||
list.set(1, "k");
|
||||
assertEquals(List.of("u", "k", "f", "e"), list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequencedCollectionIterator() {
|
||||
List<String> list = new ArrayList<>(List.of("a", "b", "c", "d")).reversed();
|
||||
Iterator<String> it = list.iterator();
|
||||
assertEquals("d", it.next());
|
||||
assertEquals("c", it.next());
|
||||
it.remove();
|
||||
assertEquals(List.of("d", "b", "a"), list);
|
||||
list = new ArrayList<>(List.of("a", "b", "c", "d")).reversed();
|
||||
ListIterator<String> lit = list.listIterator();
|
||||
assertEquals("d", lit.next());
|
||||
assertEquals("c", lit.next());
|
||||
assertEquals("b", lit.next());
|
||||
lit.remove();
|
||||
assertEquals("c", lit.previous());
|
||||
assertEquals(0, lit.previousIndex());
|
||||
assertEquals(1, lit.nextIndex());
|
||||
lit.remove();
|
||||
assertEquals(0, lit.previousIndex());
|
||||
assertEquals(1, lit.nextIndex());
|
||||
lit.add("x");
|
||||
assertEquals(List.of("d", "x", "a"), list);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,12 @@ package org.teavm.classlib.java.util;
|
|||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import org.junit.Test;
|
||||
|
@ -233,4 +235,79 @@ public class LinkedListTest {
|
|||
list.push("bar");
|
||||
assertEquals("bar", list.peek());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequencedCollectionReadOnly() {
|
||||
List<String> list = new LinkedList<>(List.of("0", "1", "2", "3", "4", "5", "6"));
|
||||
List<String> reversed = list.reversed();
|
||||
assertEquals("1", reversed.get(5));
|
||||
Iterator<String> it = reversed.iterator();
|
||||
assertEquals("6", it.next());
|
||||
assertEquals("5", it.next());
|
||||
assertEquals("6", reversed.getFirst());
|
||||
assertEquals("0", reversed.getLast());
|
||||
ListIterator<String> lit = reversed.listIterator();
|
||||
assertFalse(lit.hasPrevious());
|
||||
assertTrue(lit.hasNext());
|
||||
assertEquals("6", lit.next());
|
||||
assertEquals("5", lit.next());
|
||||
assertEquals("5", lit.previous());
|
||||
lit = reversed.listIterator(2);
|
||||
assertEquals("4", lit.next());
|
||||
lit.previous();
|
||||
assertEquals("5", lit.previous());
|
||||
assertSame(list, reversed.reversed());
|
||||
List<String> subList = reversed.subList(3, 5);
|
||||
assertEquals("2", subList.getLast());
|
||||
assertEquals("3", subList.listIterator().next());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
subList.forEach(sb::append);
|
||||
assertEquals("32", sb.toString());
|
||||
List<Integer> duplicates = new LinkedList<>(List.of(0, 1, 2, 3, 2, 1, 0, 0)).reversed();
|
||||
assertEquals(2, duplicates.indexOf(1));
|
||||
assertEquals(6, duplicates.lastIndexOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequencedCollectionMutations() {
|
||||
List<String> list = new LinkedList<>(List.of("a", "b", "c", "d"));
|
||||
assertEquals("a", list.removeFirst());
|
||||
assertEquals("d", list.removeLast());
|
||||
list.addFirst("u");
|
||||
list.addLast("e");
|
||||
assertEquals(List.of("u", "b", "c", "e"), list);
|
||||
list = new LinkedList<>(List.of("a", "b", "c", "d")).reversed();
|
||||
assertEquals("d", list.removeFirst());
|
||||
assertEquals("a", list.removeLast());
|
||||
list.addFirst("u");
|
||||
list.addLast("e");
|
||||
assertEquals("c", list.remove(1));
|
||||
list.add(2, "f");
|
||||
list.set(1, "k");
|
||||
assertEquals(List.of("u", "k", "f", "e"), list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequencedCollectionIterator() {
|
||||
List<String> list = new LinkedList<>(List.of("a", "b", "c", "d")).reversed();
|
||||
Iterator<String> it = list.iterator();
|
||||
assertEquals("d", it.next());
|
||||
assertEquals("c", it.next());
|
||||
it.remove();
|
||||
assertEquals(List.of("d", "b", "a"), list);
|
||||
list = new LinkedList<>(List.of("a", "b", "c", "d")).reversed();
|
||||
ListIterator<String> lit = list.listIterator();
|
||||
assertEquals("d", lit.next());
|
||||
assertEquals("c", lit.next());
|
||||
assertEquals("b", lit.next());
|
||||
lit.remove();
|
||||
assertEquals("c", lit.previous());
|
||||
assertEquals(0, lit.previousIndex());
|
||||
assertEquals(1, lit.nextIndex());
|
||||
lit.remove();
|
||||
assertEquals(0, lit.previousIndex());
|
||||
assertEquals(1, lit.nextIndex());
|
||||
lit.add("x");
|
||||
assertEquals(List.of("d", "x", "a"), list);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,14 @@ package org.teavm.classlib.java.util;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.teavm.junit.TeaVMTestRunner;
|
||||
|
@ -131,4 +134,48 @@ public class ListTest {
|
|||
|
||||
assertEquals("isEmpty works properly", expected.length == 0, actual.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequencedCollection() {
|
||||
List<String> list = List.of("0", "1", "2", "3", "4", "5", "6");
|
||||
List<String> reversed = list.reversed();
|
||||
assertEquals("1", reversed.get(5));
|
||||
Iterator<String> it = reversed.iterator();
|
||||
assertEquals("6", it.next());
|
||||
assertEquals("5", it.next());
|
||||
assertEquals("6", reversed.getFirst());
|
||||
assertEquals("0", reversed.getLast());
|
||||
ListIterator<String> lit = reversed.listIterator();
|
||||
assertFalse(lit.hasPrevious());
|
||||
assertTrue(lit.hasNext());
|
||||
assertEquals("6", lit.next());
|
||||
assertEquals("5", lit.next());
|
||||
assertEquals("5", lit.previous());
|
||||
lit = reversed.listIterator(2);
|
||||
assertEquals("4", lit.next());
|
||||
lit.previous();
|
||||
assertEquals("5", lit.previous());
|
||||
assertSame(list, reversed.reversed());
|
||||
List<String> subList = reversed.subList(3, 5);
|
||||
assertEquals("2", subList.getLast());
|
||||
assertEquals("3", subList.listIterator().next());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
subList.forEach(sb::append);
|
||||
assertEquals("32", sb.toString());
|
||||
List<Integer> duplicates = List.of(0, 1, 2, 3, 2, 1, 0, 0).reversed();
|
||||
assertEquals(2, duplicates.indexOf(1));
|
||||
assertEquals(6, duplicates.lastIndexOf(1));
|
||||
try {
|
||||
list.removeFirst();
|
||||
fail();
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// ok
|
||||
}
|
||||
try {
|
||||
reversed.removeLast();
|
||||
fail();
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// ok
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user