Fix range checking in AbstractList.subList. Add RandomAccess to object returned by Arrays.asList

This commit is contained in:
Alexey Andreev 2016-12-03 11:05:33 +03:00
parent c25dd1a99d
commit 10bb4ef3da
4 changed files with 77 additions and 14 deletions

View File

@ -144,7 +144,7 @@ public abstract class TAbstractList<E> extends TAbstractCollection<E> implements
if (fromIndex > toIndex) { if (fromIndex > toIndex) {
throw new TIllegalArgumentException(); throw new TIllegalArgumentException();
} }
if (fromIndex < 0 || toIndex >= size()) { if (fromIndex < 0 || toIndex > size()) {
throw new TIndexOutOfBoundsException(); throw new TIndexOutOfBoundsException();
} }
if (this instanceof TRandomAccess) { if (this instanceof TRandomAccess) {

View File

@ -17,6 +17,7 @@ package org.teavm.classlib.java.util;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.Objects; import java.util.Objects;
import java.util.RandomAccess;
import org.teavm.classlib.java.lang.TClass; import org.teavm.classlib.java.lang.TClass;
import org.teavm.classlib.java.lang.TComparable; import org.teavm.classlib.java.lang.TComparable;
import org.teavm.classlib.java.lang.TDouble; import org.teavm.classlib.java.lang.TDouble;
@ -1493,19 +1494,27 @@ public class TArrays extends TObject {
@SafeVarargs @SafeVarargs
public static <T> TList<T> asList(final T... a) { public static <T> TList<T> asList(final T... a) {
return new TAbstractList<T>() { return new ArrayAsList<>(a);
}
static class ArrayAsList<T> extends TAbstractList<T> implements RandomAccess {
private T[] array;
public ArrayAsList(T[] array) {
this.array = array;
}
@Override public T get(int index) { @Override public T get(int index) {
return a[index]; return array[index];
} }
@Override public T set(int index, T element) { @Override public T set(int index, T element) {
T old = a[index]; T old = array[index];
a[index] = element; array[index] = element;
return old; return old;
} }
@Override public int size() { @Override public int size() {
return a.length; return array.length;
} }
};
} }
public static TString deepToString(Object[] a) { public static TString deepToString(Object[] a) {

View File

@ -113,4 +113,49 @@ public class ArrayListTest {
} }
return list; return list;
} }
@Test
public void subListRange() {
List<Integer> list = fillFromZeroToNine();
List<Integer> sublist = list.subList(0, 10);
assertEquals(10, sublist.size());
sublist = list.subList(0, 0);
assertEquals(0, sublist.size());
sublist = list.subList(10, 10);
assertEquals(0, sublist.size());
sublist = list.subList(5, 5);
assertEquals(0, sublist.size());
try {
list.subList(-1, -1);
fail("Expected IOOBE for negative indexes");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
list.subList(11, 11);
fail("Expected IOOBE for indexes beyond size");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
list.subList(-1, 11);
fail("Expected IOOBE for indexes beyond limits");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
list.subList(5, 4);
fail("Expected IAE for lowerIndex > upperIndex");
} catch (IllegalArgumentException e) {
// OK
}
}
} }

View File

@ -116,4 +116,13 @@ public class CollectionsTest {
assertEquals(-1, Collections.lastIndexOfSubList(list, Arrays.asList(5, 1))); assertEquals(-1, Collections.lastIndexOfSubList(list, Arrays.asList(5, 1)));
assertEquals(0, Collections.lastIndexOfSubList(list, list)); assertEquals(0, Collections.lastIndexOfSubList(list, list));
} }
@Test
public void shuffleWorksOnArrayAsList() {
List<Integer> list = Arrays.asList(1, 2, 3, 4);
Collections.shuffle(list);
for (int i = 1; i <= 4; ++i) {
assertTrue("List expected to contain " + i, list.contains(i));
}
}
} }