mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds incomplete implementation of LinkedList
This commit is contained in:
parent
e9af85534f
commit
1bd0a42103
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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 org.teavm.classlib.java.lang.TIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public abstract class TAbstractSequentialList<E> extends TAbstractList<E> {
|
||||
@Override
|
||||
public E get(int index) {
|
||||
if (index < 0) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
TIterator<E> iter = listIterator(index);
|
||||
return iter.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
if (index < 0) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
TListIterator<E> iter = listIterator(index);
|
||||
E old = iter.next();
|
||||
iter.set(element);
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
if (index < 0) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
TListIterator<E> iter = listIterator(index);
|
||||
iter.add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
if (index < 0) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
TListIterator<E> iter = listIterator(index);
|
||||
E elem = iter.next();
|
||||
iter.remove();
|
||||
return elem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, TCollection<? extends E> c) {
|
||||
if (index < 0) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
TListIterator<E> iter = listIterator(index);
|
||||
boolean added = false;
|
||||
for (TIterator<? extends E> srcIter = c.iterator(); srcIter.hasNext();) {
|
||||
iter.add(srcIter.next());
|
||||
iter.next();
|
||||
added = true;
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TIterator<E> iterator() {
|
||||
return listIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract TListIterator<E> listIterator(int index);
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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.util.ConcurrentModificationException;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TLinkedList<E> extends TAbstractSequentialList<E> {
|
||||
static class Entry<E> {
|
||||
E item;
|
||||
Entry<E> next;
|
||||
Entry<E> previous;
|
||||
}
|
||||
private Entry<E> firstEntry;
|
||||
private Entry<E> lastEntry;
|
||||
private int size;
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
firstEntry = null;
|
||||
lastEntry = null;
|
||||
size = 0;
|
||||
modCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TListIterator<E> listIterator() {
|
||||
return new SequentialListIterator(firstEntry, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TListIterator<E> listIterator(int index) {
|
||||
if (index <= size / 2) {
|
||||
TListIterator<E> iter = listIterator();
|
||||
while (index-- > 0) {
|
||||
if (!iter.hasNext()) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
iter.next();
|
||||
}
|
||||
return iter;
|
||||
} else {
|
||||
TListIterator<E> iter = new SequentialListIterator(null, lastEntry);
|
||||
while (index++ < size) {
|
||||
if (!iter.hasPrevious()) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
iter.previous();
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
}
|
||||
|
||||
private class SequentialListIterator implements TListIterator<E> {
|
||||
private Entry<E> nextEntry = firstEntry;
|
||||
private Entry<E> prevEntry = null;
|
||||
private Entry<E> currentEntry;
|
||||
private int index;
|
||||
private int version = modCount;
|
||||
|
||||
public SequentialListIterator(Entry<E> nextEntry, Entry<E> prevEntry) {
|
||||
this.nextEntry = nextEntry;
|
||||
this.prevEntry = prevEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return nextEntry != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
checkConcurrentModification();
|
||||
if (nextEntry == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
E result = nextEntry.item;
|
||||
currentEntry = nextEntry;
|
||||
prevEntry = nextEntry;
|
||||
nextEntry = nextEntry.next;
|
||||
++index;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (currentEntry == null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
currentEntry.next.previous = currentEntry.next;
|
||||
currentEntry.previous.next = currentEntry.next;
|
||||
if (currentEntry == firstEntry) {
|
||||
firstEntry = firstEntry.next;
|
||||
} else if (currentEntry == lastEntry) {
|
||||
lastEntry = lastEntry.previous;
|
||||
}
|
||||
if (currentEntry == prevEntry) {
|
||||
prevEntry = nextEntry.previous;
|
||||
} else if (currentEntry == nextEntry) {
|
||||
nextEntry = prevEntry.next;
|
||||
}
|
||||
--index;
|
||||
--size;
|
||||
++modCount;
|
||||
version = modCount;
|
||||
currentEntry = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return prevEntry != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E previous() {
|
||||
checkConcurrentModification();
|
||||
if (prevEntry == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
currentEntry = prevEntry;
|
||||
E result = prevEntry.item;
|
||||
nextEntry = prevEntry;
|
||||
prevEntry = prevEntry.previous;
|
||||
--index;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return index - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(E e) {
|
||||
if (currentEntry == null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
checkConcurrentModification();
|
||||
currentEntry.item = e;
|
||||
currentEntry = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(E e) {
|
||||
checkConcurrentModification();
|
||||
Entry<E> newEntry = new Entry<>();
|
||||
newEntry.item = e;
|
||||
newEntry.previous = prevEntry;
|
||||
newEntry.next = nextEntry;
|
||||
if (prevEntry != null) {
|
||||
prevEntry.next = newEntry;
|
||||
} else {
|
||||
firstEntry = newEntry;
|
||||
}
|
||||
if (nextEntry != null) {
|
||||
nextEntry.previous = newEntry;
|
||||
} else {
|
||||
lastEntry = newEntry;
|
||||
}
|
||||
prevEntry = newEntry;
|
||||
++size;
|
||||
++modCount;
|
||||
version = modCount;
|
||||
currentEntry = null;
|
||||
}
|
||||
|
||||
private void checkConcurrentModification() {
|
||||
if (version < modCount) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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 static org.junit.Assert.*;
|
||||
import java.util.*;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class LinkedListTest {
|
||||
@Test
|
||||
public void emptyListCreated() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
assertTrue(list.isEmpty());
|
||||
assertEquals(0, list.size());
|
||||
assertFalse(list.iterator().hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elementAdded() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.add("foo");
|
||||
Iterator<String> iter = list.iterator();
|
||||
assertEquals("foo", iter.next());
|
||||
assertEquals(1, list.size());
|
||||
assertFalse(iter.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elementRetrievedByIndex() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.add("foo");
|
||||
list.add("bar");
|
||||
list.add("baz");
|
||||
assertEquals("foo", list.get(0));
|
||||
assertEquals("bar", list.get(1));
|
||||
assertEquals("baz", list.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listIteratorPositioned() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.addAll(Arrays.asList("1", "2", "3", "a", "b"));
|
||||
ListIterator<String> iter = list.listIterator(1);
|
||||
assertEquals(1, iter.nextIndex());
|
||||
assertEquals(0, iter.previousIndex());
|
||||
assertTrue(iter.hasNext());
|
||||
assertTrue(iter.hasPrevious());
|
||||
assertEquals("2", iter.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listIteratorMoved() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.addAll(Arrays.asList("1", "2", "3", "a", "b"));
|
||||
ListIterator<String> iter = list.listIterator(1);
|
||||
assertEquals("2", iter.next());
|
||||
assertEquals("3", iter.next());
|
||||
assertEquals("a", iter.next());
|
||||
assertEquals("a", iter.previous());
|
||||
assertEquals("3", iter.previous());
|
||||
assertEquals(2, iter.nextIndex());
|
||||
assertEquals(1, iter.previousIndex());
|
||||
}
|
||||
|
||||
@Test(expected = NoSuchElementException.class)
|
||||
public void listInteratorCantMoveBeyondLowerBound() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.addAll(Arrays.asList("1", "2", "3", "a", "b"));
|
||||
ListIterator<String> iter = list.listIterator(1);
|
||||
assertEquals("1", iter.previous());
|
||||
iter.previous();
|
||||
}
|
||||
|
||||
@Test(expected = NoSuchElementException.class)
|
||||
public void listInteratorCantMoveBeyondUpperBound() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.addAll(Arrays.asList("1", "2", "3", "a", "b"));
|
||||
ListIterator<String> iter = list.listIterator(4);
|
||||
assertEquals("b", iter.next());
|
||||
iter.next();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listIteratorRemovesItem() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.addAll(Arrays.asList("1", "2", "3", "a", "b"));
|
||||
ListIterator<String> iter = list.listIterator(2);
|
||||
assertEquals("3", iter.next());
|
||||
iter.remove();
|
||||
assertEquals(2, iter.nextIndex());
|
||||
assertEquals("a", iter.next());
|
||||
assertArrayEquals(new String[] { "1", "2", "a", "b" }, list.toArray(new String[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listIteratorAddsItem() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.addAll(Arrays.asList("1", "2", "3", "a", "b"));
|
||||
ListIterator<String> iter = list.listIterator(2);
|
||||
iter.add("*");
|
||||
assertEquals("3", iter.next());
|
||||
assertArrayEquals(new String[] { "1", "2", "*", "3", "a", "b" }, list.toArray(new String[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listIteratorReplacesItem() {
|
||||
LinkedList<String> list = new LinkedList<>();
|
||||
list.addAll(Arrays.asList("1", "2", "3", "a", "b"));
|
||||
ListIterator<String> iter = list.listIterator(2);
|
||||
iter.next();
|
||||
iter.set("*");
|
||||
assertEquals("a", iter.next());
|
||||
assertArrayEquals(new String[] { "1", "2", "*", "a", "b" }, list.toArray(new String[0]));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user