Implements some of java.util.Collection

This commit is contained in:
konsoletyper 2014-03-20 12:57:33 +04:00
parent a657eaf524
commit b91742fa2d
3 changed files with 224 additions and 22 deletions

View File

@ -124,7 +124,7 @@ public class ArrayNativeGenerator implements Generator, DependencyPlugin {
writer.append("return ").appendMethodBody(methodRef).append("(item);").softNewLine();
writer.outdent().append("} else ");
}
writer.append("{").softNewLine();
writer.append("{").indent().softNewLine();
writer.append("return item;").softNewLine();
writer.outdent().append("}").softNewLine();
}

View File

@ -15,6 +15,7 @@
*/
package org.teavm.classlib.java.util;
import java.util.RandomAccess;
import org.teavm.classlib.java.lang.*;
/**
@ -156,6 +157,9 @@ public class TCollections extends TObject {
}
public static <T> void sort(TList<T> list, TComparator<? super T> c) {
if (c == null) {
c = naturalOrder;
}
@SuppressWarnings("unchecked")
T[] array = (T[])new Object[list.size()];
list.toArray(array);
@ -166,21 +170,166 @@ public class TCollections extends TObject {
}
public static <T extends TComparable<? super T>> void sort(TList<T> list) {
sort(list, new TComparator<T>() {
@Override public int compare(T o1, T o2) {
return o1 != null ? o1.compareTo(o2) : -o2.compareTo(o1);
}
});
sort(list, naturalOrder);
}
public static void reverse(TList<?> list) {
reverse(list, 0, list.size());
}
public static <T> int binarySearch(TList<? extends TComparable<? super T>> list, T key) {
return binarySearch(list, key, naturalOrder);
}
private static TComparator<Object> naturalOrder = new TComparator<Object>() {
@SuppressWarnings("unchecked") @Override public int compare(Object o1, Object o2) {
return o1 != null ? ((TComparable<Object>)o1).compareTo(o2) : -((TComparable<Object>)o2).compareTo(o1);
}
};
public static <T> int binarySearch(TList<? extends T> list, T key, TComparator<? super T> c) {
if (!(list instanceof TRandomAccess)) {
list = new TArrayList<>(list);
}
if (c == null) {
c = naturalOrder;
}
int l = 0;
int u = list.size() - 1;
while (true) {
int i = (l + u) / 2;
T e = list.get(i);
int cmp = c.compare(key, e);
if (cmp == 0) {
return i;
} else if (cmp < 0) {
u = i - 1;
if (u < l) {
return -i - 1;
}
} else {
l = i + 1;
if (l > u) {
return -i - 2;
}
}
}
}
public static void shuffle(TList<?> list) {
shuffle(list, new TRandom());
}
@SuppressWarnings("unchecked")
public static void shuffle(TList<?> list, TRandom rnd) {
if (list instanceof TRandomAccess) {
shuffleRandomAccess(list, rnd);
} else {
TList<Object> randomAccess = new TArrayList<>(list);
shuffleRandomAccess(list, rnd);
list.clear();
((TList<Object>)list).addAll(randomAccess);
}
}
private static void shuffleRandomAccess(TList<?> list, TRandom rnd) {
for (int i = list.size() - 1; i > 0; --i) {
int j = rnd.next(i + 1);
swap(list, i, j);
}
}
public static <T> void fill(TList<? super T> list, T obj) {
if (list instanceof RandomAccess) {
for (int i = 0; i < list.size(); ++i) {
list.set(i, obj);
}
} else {
for (TListIterator<? super T> iter = list.listIterator(); iter.hasNext();) {
iter.next();
iter.set(obj);
}
}
}
public static <T> void copy(TList<? super T> dest, TList<? extends T> src) {
if (src.size() > dest.size()) {
throw new IndexOutOfBoundsException();
}
if (src instanceof RandomAccess && dest instanceof RandomAccess) {
for (int i = 0; i < src.size(); ++i) {
dest.set(i, src.get(i));
}
} else {
TListIterator<? extends T> srcIter = src.listIterator();
TListIterator<? super T> destIter = dest.listIterator();
while (srcIter.hasNext()) {
destIter.next();
destIter.set(srcIter.next());
}
}
}
public static <T extends Object & TComparable<? super T>> T min(TCollection<? extends T> coll) {
return min(coll, naturalOrder);
}
public static <T> T min(TCollection<? extends T> coll, TComparator<? super T> comp) {
if (comp == null) {
comp = naturalOrder;
}
TIterator<? extends T> iter = coll.iterator();
T min = iter.next();
while (iter.hasNext()) {
T elem = iter.next();
if (comp.compare(elem, min) < 0) {
min = elem;
}
}
return min;
}
public static <T extends Object & TComparable<? super T>> T max(TCollection<? extends T> coll) {
return max(coll, naturalOrder);
}
public static <T> T max(TCollection<? extends T> coll, TComparator<? super T> comp) {
if (comp == null) {
comp = naturalOrder;
}
TIterator<? extends T> iter = coll.iterator();
T max = iter.next();
while (iter.hasNext()) {
T elem = iter.next();
if (comp.compare(elem, max) > 0) {
max = elem;
}
}
return max;
}
public static void rotate(TList<?> list, int distance) {
distance %= list.size();
if (distance < 0) {
distance += list.size();
}
if (distance == 0) {
return;
}
reverse(list, 0, list.size());
reverse(list, 0, distance);
reverse(list, distance, list.size());
}
private static void reverse(TList<?> list, int from, int to) {
@SuppressWarnings("unchecked")
TList<Object> safeList = (TList<Object>)list;
int half = safeList.size() / 2;
for (int i = 0; i < half; ++i) {
int half = (from + to) / 2;
int j = to - 1;
for (int i = from; i < half; ++i, --j) {
Object tmp = safeList.get(i);
safeList.set(i, safeList.get(safeList.size() - i - 1));
safeList.set(safeList.size() - i - 1, tmp);
safeList.set(i, safeList.get(j));
safeList.set(j, tmp);
}
}
}

View File

@ -15,7 +15,7 @@
*/
package org.teavm.classlib.java.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -27,18 +27,71 @@ import org.junit.Test;
* @author Alexey Andreev
*/
public class CollectionsTest {
private List<Integer> array;
@Test
public void listSorted() {
List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(2, 5, 7, 3, 5, 6));
Collections.sort(list);
assertEquals(Integer.valueOf(2), list.get(0));
assertEquals(Integer.valueOf(3), list.get(1));
assertEquals(Integer.valueOf(5), list.get(2));
assertEquals(Integer.valueOf(5), list.get(3));
assertEquals(Integer.valueOf(6), list.get(4));
assertEquals(Integer.valueOf(7), list.get(5));
}
@Test
public void arraySorted() {
array = new ArrayList<>();
array.addAll(Arrays.asList(2, 5, 7, 3, 5, 6));
Collections.sort(array);
assertEquals(Integer.valueOf(2), array.get(0));
assertEquals(Integer.valueOf(3), array.get(1));
assertEquals(Integer.valueOf(5), array.get(2));
assertEquals(Integer.valueOf(5), array.get(3));
assertEquals(Integer.valueOf(6), array.get(4));
assertEquals(Integer.valueOf(7), array.get(5));
public void binarySearchWorks() {
List<Integer> list = new ArrayList<>(Arrays.asList(2, 4, 6, 8, 10, 12, 14, 16));
assertEquals(3, Collections.binarySearch(list, 8));
assertEquals(7, Collections.binarySearch(list, 16));
assertEquals(0, Collections.binarySearch(list, 2));
assertEquals(-1, Collections.binarySearch(list, 1));
assertEquals(-2, Collections.binarySearch(list, 3));
assertEquals(-3, Collections.binarySearch(list, 5));
assertEquals(-8, Collections.binarySearch(list, 15));
assertEquals(-9, Collections.binarySearch(list, 17));
}
@Test
public void findsMinimum() {
List<Integer> list = Arrays.asList(6, 5, 7, 3, 5, 6);
assertEquals((Integer)3, Collections.min(list));
}
@Test
public void findsMaximum() {
List<Integer> list = Arrays.asList(6, 5, 7, 3, 5, 6);
assertEquals((Integer)7, Collections.max(list));
}
@Test
public void fills() {
List<Integer> list = new ArrayList<>(Arrays.asList(6, 5, 7, 3, 5, 6));
Collections.fill(list, 9);
assertEquals(6, list.size());
assertEquals((Integer)9, list.get(0));
assertEquals((Integer)9, list.get(5));
assertEquals((Integer)9, list.get(2));
}
@Test
public void copies() {
List<Integer> list = new ArrayList<>(Arrays.asList(6, 5, 7, 3, 5, 6));
List<Integer> dest = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
Collections.copy(dest, list);
assertEquals(7, dest.size());
assertEquals((Integer)6, dest.get(0));
assertEquals((Integer)5, dest.get(1));
assertEquals((Integer)5, dest.get(4));
assertEquals((Integer)6, dest.get(5));
assertEquals((Integer)7, dest.get(6));
}
@Test
public void rotates() {
List<Integer> list = new ArrayList<>(Arrays.asList(2, 5, 7, 3, 5, 6));
Collections.rotate(list, 2);
assertArrayEquals(new Integer[] { 5, 6, 2, 5, 7, 3 }, list.toArray(new Integer[0]));
}
}