Revision: 6340 Author: j...@google.com Date: Fri Oct 9 15:22:16 2009 Log: Add List.subList and implementations.
Patch by: w...@google.com Review by: jat http://code.google.com/p/google-web-toolkit/source/detail?r=6340 Modified: /trunk/user/super/com/google/gwt/emul/java/util/AbstractList.java /trunk/user/super/com/google/gwt/emul/java/util/ArrayList.java /trunk/user/super/com/google/gwt/emul/java/util/Collections.java /trunk/user/super/com/google/gwt/emul/java/util/LinkedList.java /trunk/user/super/com/google/gwt/emul/java/util/List.java /trunk/user/super/com/google/gwt/emul/java/util/Vector.java /trunk/user/test/com/google/gwt/emultest/java/util/ListTestBase.java ======================================= --- /trunk/user/super/com/google/gwt/emul/java/util/AbstractList.java Wed May 13 14:30:29 2009 +++ /trunk/user/super/com/google/gwt/emul/java/util/AbstractList.java Fri Oct 9 15:22:16 2009 @@ -109,6 +109,74 @@ AbstractList.this.set(last, o); } } + + private static class SubList<E> extends AbstractList<E> { + private final List<E> wrapped; + private final int fromIndex; + private int size; + + public SubList(List<E> wrapped, int fromIndex, int toIndex) { + this.wrapped = wrapped; + this.fromIndex = fromIndex; + size = getSize(fromIndex, toIndex); + if (fromIndex > toIndex) { + throw new IllegalArgumentException("fromIndex: " + fromIndex + + " > toIndex: " + toIndex); + } + if (fromIndex < 0) { + throw new IndexOutOfBoundsException("fromIndex: " + fromIndex + + " < 0"); + } + if (toIndex > wrapped.size()) { + throw new IndexOutOfBoundsException("toIndex: " + toIndex + + " > wrapped.size() " + wrapped.size()); + } + } + + @Override + public void add(int index, E element) { + checkIndexForAdd(index); + size++; + wrapped.add(fromIndex + index, element); + } + + @Override + public E get(int index) { + checkIndex(index); + return wrapped.get(fromIndex + index); + } + + @Override + public E remove(int index) { + checkIndex(index); + E result = wrapped.remove(fromIndex + index); + size--; + return result; + } + + @Override + public E set(int index, E element) { + checkIndex(index); + return wrapped.set(fromIndex + index, element); + } + + @Override + public int size() { + return size; + } + + private void checkIndex(int index) { + checkIndex(index, size); + } + + private void checkIndexForAdd(int index) { + checkIndex(index, size - 1); + } + + private int getSize(int fromIndex, int toIndex) { + return toIndex - fromIndex; + } + } protected static void checkIndex(int index, int size) { if (index < 0 || index >= size) { @@ -233,9 +301,9 @@ throw new UnsupportedOperationException("Set not supported on this list"); } - // TODO(jat): implement -// public List<E> subList(int fromIndex, int toIndex) { -// } + public List<E> subList(int fromIndex, int toIndex) { + return new SubList<E>(this, fromIndex, toIndex); + } protected void removeRange(int fromIndex, int endIndex) { ListIterator<E> iter = listIterator(fromIndex); ======================================= --- /trunk/user/super/com/google/gwt/emul/java/util/ArrayList.java Fri Jun 13 17:45:25 2008 +++ /trunk/user/super/com/google/gwt/emul/java/util/ArrayList.java Fri Oct 9 15:22:16 2009 @@ -275,11 +275,6 @@ setCapacity(array, newSize); size = newSize; } - - // TODO(jat): implement -// @Override -// List<E> subList(int fromIndex, int toIndex) { -// } @SuppressWarnings("unchecked") private void clearImpl() { ======================================= --- /trunk/user/super/com/google/gwt/emul/java/util/Collections.java Tue Aug 4 10:48:23 2009 +++ /trunk/user/super/com/google/gwt/emul/java/util/Collections.java Fri Oct 9 15:22:16 2009 @@ -148,6 +148,10 @@ public T set(int index, T element) { throw new UnsupportedOperationException(); } + + public List<T> subList(int fromIndex, int toIndex) { + return new UnmodifiableList<T>(list.subList(fromIndex, toIndex)); + } } static class UnmodifiableMap<K, V> implements Map<K, V> { ======================================= --- /trunk/user/super/com/google/gwt/emul/java/util/LinkedList.java Fri Jun 13 17:45:25 2008 +++ /trunk/user/super/com/google/gwt/emul/java/util/LinkedList.java Fri Oct 9 15:22:16 2009 @@ -28,6 +28,8 @@ List<E>, Queue<E>, Serializable { /* * This implementation uses a doubly-linked circular list with a header node. + * + * TODO(jat): add more efficient subList implementation. */ /** @@ -301,11 +303,6 @@ public int size() { return size; } - - // TODO(jat): implement -// @Override -// List<E> subList(final int fromIndex, final int toIndex) { -// } private void addBefore(E o, Node<E> target) { new Node<E>(o, target); ======================================= --- /trunk/user/super/com/google/gwt/emul/java/util/List.java Fri Jun 13 17:45:25 2008 +++ /trunk/user/super/com/google/gwt/emul/java/util/List.java Fri Oct 9 15:22:16 2009 @@ -67,8 +67,7 @@ int size(); - // TODO(jat): add back when we implement in all List - // List<E> subList(int fromIndex, int toIndex); + List<E> subList(int fromIndex, int toIndex); Object[] toArray(); ======================================= --- /trunk/user/super/com/google/gwt/emul/java/util/Vector.java Fri Jun 13 17:45:25 2008 +++ /trunk/user/super/com/google/gwt/emul/java/util/Vector.java Fri Oct 9 15:22:16 2009 @@ -222,11 +222,10 @@ return arrayList.size(); } - // TODO(jat): add back when ArrayList actually supports subList -// @Override -// public List<E> subList(int fromIndex, int toIndex) { -// return arrayList.subList(fromIndex, toIndex); -// } + @Override + public List<E> subList(int fromIndex, int toIndex) { + return arrayList.subList(fromIndex, toIndex); + } @Override public Object[] toArray() { ======================================= --- /trunk/user/test/com/google/gwt/emultest/java/util/ListTestBase.java Wed Apr 23 11:35:08 2008 +++ /trunk/user/test/com/google/gwt/emultest/java/util/ListTestBase.java Fri Oct 9 15:22:16 2009 @@ -17,10 +17,13 @@ import org.apache.commons.collections.TestArrayList; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.ListIterator; + /** * Tests List, and, by extension AbstractList. Uses inheritance to inherit all * of Apache's TestList and TestCollection. @@ -182,4 +185,101 @@ } } } -} + + public void testSubList() { + List<Integer> wrappedList = createListWithContent(new int[]{1, 2, 3, 4, 5}); + List<Integer> testList = wrappedList.subList(1, 4); + assertEquals(3, testList.size()); + + assertEquals(testList, Arrays.asList(2, 3, 4)); + checkListSizeAndContent(testList, new int[]{2, 3, 4}); + testList.add(1, 6); + assertEquals(testList, Arrays.asList(2, 6, 3, 4)); + checkListSizeAndContent(testList, new int[]{2, 6, 3, 4}); + assertEquals(wrappedList, Arrays.asList(1, 2, 6, 3, 4, 5)); + checkListSizeAndContent(wrappedList, new int[]{1, 2, 6, 3, 4, 5}); + testList.remove(2); + assertEquals(testList, Arrays.asList(2, 6, 4)); + checkListSizeAndContent(testList, new int[]{2, 6, 4}); + + try { + testList.remove(3); + fail("Expected remove to fail"); + } catch (IndexOutOfBoundsException e) { + } + + checkListSizeAndContent(wrappedList, new int[]{1, 2, 6, 4, 5}); + testList.set(0, 7); + checkListSizeAndContent(testList, new int[]{7, 6, 4}); + checkListSizeAndContent(wrappedList, new int[]{1, 7, 6, 4, 5}); + + try { + wrappedList.subList(-1, 5); + fail("expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + } + + try { + wrappedList.subList(0, 15); + fail("expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + } + + try { + wrappedList.subList(5, 1); + fail("expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + } + + try { + wrappedList.subList(0, 1).add(2, 5); + fail("expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + } + + try { + wrappedList.subList(0, 1).add(-1, 5); + fail("expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + } + + try { + wrappedList.subList(0, 1).get(1); + fail("expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + } + + try { + wrappedList.subList(0, 1).get(-1); + fail("expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + } + + try { + wrappedList.subList(0, 1).set(2, 2); + fail("expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + } + + try { + wrappedList.subList(0, 1).set(-1, 5); + fail("expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + } + } + + private void checkListSizeAndContent(List<Integer> in, int[] expected) { + assertEquals(expected.length, in.size()); + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], (int) in.get(i)); + } + } + + private List<Integer> createListWithContent(int[] in) { + List<Integer> results = new ArrayList<Integer>(); + for (int i = 0; i < in.length; i++) { + results.add(in[i]); + } + return results; + } +} --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---