From cfc2049b6b22df535c64e40a445f8a1a73cef63b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Ferr=C3=A9?= Date: Fri, 30 May 2014 19:32:08 +0200 Subject: [PATCH 01/14] Make subList implementation more efficient for LinkedList --- .../implementations/ImmutableLinkedList.java | 33 ++++++++++++------- .../src/test/ImmutableLinkedListTest.java | 17 ++++++++++ .../src/test/ImmutableListTest.java | 4 +-- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java index 90a383c..8a666d1 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java @@ -201,8 +201,8 @@ public E last() throws NoSuchElementException { @SuppressWarnings("unchecked") public ImmutableList subList(int fromIndex, int toIndex) throws - IndexOutOfBoundsException, - IllegalArgumentException { + IndexOutOfBoundsException, + IllegalArgumentException { if (fromIndex < 0 || toIndex > size()) throw new IndexOutOfBoundsException(); @@ -217,15 +217,17 @@ public ImmutableList subList(int fromIndex, int toIndex) throws node = node.getNext(); ++i; } + Node subListHead = node; - E[] elems = (E[]) new Object[toIndex - fromIndex]; - while (i != toIndex) { - elems[i - fromIndex] = (E)node.getElement(); + while (i != toIndex-1) { node = node.getNext(); ++i; } + Node subListLast = node; - return new ImmutableLinkedList(elems); + return new ImmutableLinkedList(subListHead, + subListLast, + toIndex - fromIndex); } public ImmutableList reverse() { @@ -276,7 +278,7 @@ public ImmutableList cons(E elem) { public ImmutableList concat(Collection elems){ ImmutableList list = this; - for (E elem: elems){ + for (E elem: elems) { list = list.concat(elem); } return list; @@ -311,7 +313,7 @@ public ImmutableList concat(E elem) { public ImmutableList remove(Collection elems) { ImmutableList list = this; - for (E elem: elems){ + for (E elem: elems) { list = list.remove(elem); } return list; @@ -329,7 +331,7 @@ public ImmutableList remove(ImmutableList elems) { @SuppressWarnings({"unchecked"}) public ImmutableList remove(E... elems) { ImmutableList list = this; - for (int i = 0 ; i { /** Current node pointed by the iterator */ private Node currentNode; + /** Tell whether the iterator can continue or not */ + private boolean hasNext; + /** * Create a new iterator starting from the beginning of the linked list. */ public ImmutableLinkedListIterator() { currentNode = headNode(); + hasNext = (size() != 0); } public boolean hasNext() { - return currentNode != null; + return hasNext; } public E next() throws NoSuchElementException { - if (currentNode == null) + if (!hasNext()) throw new NoSuchElementException(); E elem = currentNode.getElement(); - currentNode = currentNode.getNext(); + if (currentNode == lastNode()) + hasNext = false; + else + currentNode = currentNode.getNext(); return elem; } diff --git a/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java b/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java index eb8c020..0858e8c 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java @@ -23,4 +23,21 @@ public class ImmutableLinkedListTest extends ImmutableListTest { public void setUp() { super.setUp(new ImmutableLinkedListFactory()); } + + @Test + public void SubListLinkedListTest() { + + // Test that iterators stop at the right last node for sublists + // (since they all share their structures with a superlist) + + ImmutableList subList = list.subList(1, list.size()-1); + assertEquals(1, subList.size()); + + int sizeWhenIterating = 0; + for (Integer i : subList) + ++sizeWhenIterating; + + assertEquals(subList.size(), sizeWhenIterating); + + } } diff --git a/Immutable_collections_java8_project/src/test/ImmutableListTest.java b/Immutable_collections_java8_project/src/test/ImmutableListTest.java index 7a24cc8..3475a76 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableListTest.java @@ -350,7 +350,7 @@ public void toarrayTest(){ } @Test - public void asListTest(){ + public void asListTest() { List myList = new ArrayList(); List myList2 = new ArrayList(); myList.add(1); @@ -362,7 +362,7 @@ public void asListTest(){ } @Test - public void sortTest(){ + public void sortTest() { Comparator comp = (Integer x, Integer y) -> x.compareTo(y); assertEquals(list.sort(comp),list.reverse().sort(comp)); } From 210c8ade6243d0c7d234e1e4e9e4a2ca2033c070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Ferr=C3=A9?= Date: Fri, 30 May 2014 21:02:03 +0200 Subject: [PATCH 02/14] Move Sublist iterator test to the common test suite --- .../src/test/ImmutableLinkedListTest.java | 16 ---------------- .../src/test/ImmutableListTest.java | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java b/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java index 0858e8c..dfb6d5b 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java @@ -24,20 +24,4 @@ public void setUp() { super.setUp(new ImmutableLinkedListFactory()); } - @Test - public void SubListLinkedListTest() { - - // Test that iterators stop at the right last node for sublists - // (since they all share their structures with a superlist) - - ImmutableList subList = list.subList(1, list.size()-1); - assertEquals(1, subList.size()); - - int sizeWhenIterating = 0; - for (Integer i : subList) - ++sizeWhenIterating; - - assertEquals(subList.size(), sizeWhenIterating); - - } } diff --git a/Immutable_collections_java8_project/src/test/ImmutableListTest.java b/Immutable_collections_java8_project/src/test/ImmutableListTest.java index 3475a76..7c4aaaf 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableListTest.java @@ -191,6 +191,24 @@ public void IteratorExceptionTest2() { it.remove(); } + + @Test + public void SubListIteratorTest() { + + // Test that iterators stop at the right last node for sublists + // (since they all share their structures with a superlist) + + ImmutableList subList = list.subList(1, list.size()-1); + assertEquals(1, subList.size()); + + int sizeWhenIterating = 0; + for (Integer i : subList) + ++sizeWhenIterating; + + assertEquals(subList.size(), sizeWhenIterating); + + } + @Test public void ContainsTest() { assertTrue(list.contains(1)); From 52612aa0f3add952cabdb83282f4bf60ba756dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Ferr=C3=A9?= Date: Sat, 31 May 2014 09:15:52 +0200 Subject: [PATCH 03/14] Optimize arraylist reverse method by using a view instead of creating a new list --- .../implementations/ImmutableArrayList.java | 13 +- .../ImmutableReversedArrayList.java | 119 ++++++++++++++++++ .../src/test/AllTests.java | 6 +- .../src/test/ImmutableListTest.java | 34 +++-- .../test/ImmutableReversedArrayListTest.java | 13 ++ 5 files changed, 165 insertions(+), 20 deletions(-) create mode 100644 Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java create mode 100644 Immutable_collections_java8_project/src/test/ImmutableReversedArrayListTest.java diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java index e3570ed..31e9671 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java @@ -91,7 +91,7 @@ class ImmutableArrayListIterator implements Iterator { private int size; /** - * Create a new iterator starting from the beginning of the linked list. + * Create a new iterator starting from the beginning of the list. */ public ImmutableArrayListIterator() { index = 0; @@ -171,15 +171,7 @@ public ImmutableList subList(int fromIndex, int toIndex) @Override public ImmutableList reverse() { - int j = 0; - @SuppressWarnings("unchecked") - E[] res = (E[]) new Object[size()]; - for(int i= size()-1; i >= 0; --i) - { - res[j] = get(i); - ++j; - } - return new ImmutableArrayList(res); + return new ImmutableReversedArrayList(this); } @@ -509,7 +501,6 @@ public E last() throws NoSuchElementException { return null; } - public ImmutableList clone() { return subList(0, size()); } diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java new file mode 100644 index 0000000..eee1f88 --- /dev/null +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java @@ -0,0 +1,119 @@ +package collections.implementations; + +import java.util.List; +import java.util.Collections; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import collections.interfaces.ImmutableList; + +public class ImmutableReversedArrayList extends ImmutableArrayList { + + /** The encapsulated list we delegate things to. */ + private final ImmutableArrayList list; + + /** + * Construct a reverse view of the given list. + * + * @param list the list to be reversed. + */ + public ImmutableReversedArrayList(ImmutableArrayList list) { + this.list = list; + } + + public int size() { + return list.size(); + } + + /** + * Return equivalent of index counting from the end to simulate the + * reversed view of the list. + * + * @param index The index to be reversed + **/ + private int reverseIndex(int index) { + return size() - 1 - index; + } + + public E get(int index) throws IndexOutOfBoundsException { + return list.get(reverseIndex(index)); + } + + public int indexOf(E elem) { + int index = list.indexOf(elem); + if (index != -1) + index = reverseIndex(index); + return index; + } + + public E head() throws NoSuchElementException { + return list.last(); + } + + public E last() throws NoSuchElementException { + return list.head(); + } + + @SuppressWarnings("unchecked") + public ImmutableList subList(int fromIndex, int toIndex) throws + IndexOutOfBoundsException, + IllegalArgumentException { + if (fromIndex == toIndex) + return new ImmutableArrayList(); + + return list.subList(reverseIndex(toIndex -1), + reverseIndex(fromIndex-1)).reverse(); + } + + public ImmutableList reverse() { + return list; + } + + @SuppressWarnings("unchecked") + public ImmutableList remove(int index) { + return list.remove(reverseIndex(index)).reverse(); + } + + class ReversedListIterator implements Iterator { + + /** Current index pointed by the iterator */ + private int index; + + /** + * Create a new iterator starting from the beginning of the list. + */ + public ReversedListIterator() { + index = size()-1; + } + + public boolean hasNext() { + return index >= 0 ? true : false; + } + + public E next() throws NoSuchElementException { + if (!hasNext()) + throw new NoSuchElementException(); + + E elem = list.get(index); + --index; + return elem; + } + + public void remove() throws + UnsupportedOperationException, + IllegalStateException { + throw new UnsupportedOperationException(); + } + } + + public Iterator iterator() { + return new ReversedListIterator(); + } + + @SuppressWarnings("unchecked") + public E[] toArray() { + List tmp = list.asList(); + Collections.reverse(tmp); + return (E[]) tmp.toArray(); + } +} diff --git a/Immutable_collections_java8_project/src/test/AllTests.java b/Immutable_collections_java8_project/src/test/AllTests.java index c0cd562..42ac8f1 100644 --- a/Immutable_collections_java8_project/src/test/AllTests.java +++ b/Immutable_collections_java8_project/src/test/AllTests.java @@ -5,7 +5,11 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) -@SuiteClasses({ ImmutableArrayListTest.class, ImmutableLinkedListTest.class }) +@SuiteClasses({ + ImmutableArrayListTest.class, + ImmutableLinkedListTest.class, + ImmutableReversedArrayListTest.class + }) public class AllTests { } diff --git a/Immutable_collections_java8_project/src/test/ImmutableListTest.java b/Immutable_collections_java8_project/src/test/ImmutableListTest.java index 7c4aaaf..afa3d98 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableListTest.java @@ -4,7 +4,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.util.Collections; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -43,6 +45,20 @@ public ImmutableList create() { } } +class ReversedArrayListFactory implements ImmutableListFactory { + @SuppressWarnings("unchecked") + public ImmutableList create(E... _elems) { + List tmp = Arrays.asList(_elems); + Collections.reverse(tmp); + E[] elems = (E[]) tmp.toArray(); + + return new ImmutableArrayList(elems).reverse(); + } + public ImmutableList create() { + return new ImmutableArrayList().reverse(); + } +} + public abstract class ImmutableListTest { protected ImmutableList list; @@ -191,11 +207,10 @@ public void IteratorExceptionTest2() { it.remove(); } - @Test public void SubListIteratorTest() { - // Test that iterators stop at the right last node for sublists + // Test that iterators stop at the right last element for sublists // (since they all share their structures with a superlist) ImmutableList subList = list.subList(1, list.size()-1); @@ -206,7 +221,6 @@ public void SubListIteratorTest() { ++sizeWhenIterating; assertEquals(subList.size(), sizeWhenIterating); - } @Test @@ -310,14 +324,18 @@ public void StreamTest() { @Test public void removeTest1() { - assertEquals(new ImmutableLinkedList(2, 3),list.remove(0)); - assertEquals(new ImmutableLinkedList(2, 3),list.remove(new Integer(1))); - assertEquals(new ImmutableLinkedList(3),list.remove(new Integer(1),new Integer(2))); - assertEquals(new ImmutableLinkedList(2),list.remove(new ImmutableLinkedList(1,3))); + Integer second = list.get(1); + Integer third = list.get(2); + + assertEquals(new ImmutableLinkedList(second, third),list.remove(0)); + + assertEquals(new ImmutableLinkedList(second, third),list.remove(new Integer(1))); + assertEquals(new ImmutableLinkedList(third),list.remove(new Integer(1), new Integer(2))); + assertEquals(new ImmutableLinkedList(second), list.remove(new ImmutableLinkedList(1,3))); List otherList = new ArrayList(); otherList.add(1); otherList.add(3); - assertEquals(new ImmutableLinkedList(2), list.remove(otherList)); + assertEquals(new ImmutableLinkedList(second), list.remove(otherList)); } @Test diff --git a/Immutable_collections_java8_project/src/test/ImmutableReversedArrayListTest.java b/Immutable_collections_java8_project/src/test/ImmutableReversedArrayListTest.java new file mode 100644 index 0000000..f9fe764 --- /dev/null +++ b/Immutable_collections_java8_project/src/test/ImmutableReversedArrayListTest.java @@ -0,0 +1,13 @@ +package test; + +import org.junit.Before; + + +public class ImmutableReversedArrayListTest extends ImmutableListTest { + + @Before + public void setUp() { + super.setUp(new ReversedArrayListFactory()); + } + +} From f43de4c653ff1f8ec46f16431ec7d60c7f6402f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Ferr=C3=A9?= Date: Sat, 7 Jun 2014 00:25:06 +0200 Subject: [PATCH 04/14] Change interfaces --- .../implementations/ImmutableArrayList.java | 355 ++---------------- .../implementations/ImmutableLinkedList.java | 293 ++------------- .../ImmutableReversedArrayList.java | 8 +- .../collections/interfaces/ImmutableList.java | 332 ++++++++-------- .../interfaces/InductiveIterativeList.java | 235 ++++++++++++ .../collections/interfaces/InductiveList.java | 16 +- .../collections/interfaces/IterativeList.java | 75 +++- .../src/main/Benchmarks.java | 10 +- .../src/test/ImmutableArrayListTest.java | 2 +- .../src/test/ImmutableLinkedListTest.java | 2 +- .../test/ImmutableReversedArrayListTest.java | 2 +- ...t.java => InductiveIterativeListTest.java} | 38 +- 12 files changed, 573 insertions(+), 795 deletions(-) create mode 100644 Immutable_collections_java8_project/src/collections/interfaces/InductiveIterativeList.java rename Immutable_collections_java8_project/src/test/{ImmutableListTest.java => InductiveIterativeListTest.java} (91%) diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java index 31e9671..c9bd39a 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java @@ -1,30 +1,19 @@ package collections.implementations; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; import java.util.Iterator; -import java.util.List; import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.function.BinaryOperator; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; +import collections.interfaces.InductiveIterativeList; +import collections.interfaces.IterativeList; import collections.interfaces.ImmutableList; -public class ImmutableArrayList implements ImmutableList +public class ImmutableArrayList implements InductiveIterativeList { private final E[] _array; private final int _length; - /** * Constructs an empty list with an initial capacity of 0. */ @@ -45,6 +34,10 @@ public ImmutableArrayList (E... elems) { if (elems == null) throw new NullPointerException(); + else if (elems.length == 0) { + this._array = (E[]) new Object[0]; + this._length = 0; + } else { _array = elems; @@ -52,9 +45,14 @@ public ImmutableArrayList (E... elems) } } - public ImmutableList create(E[] elems) { + public ImmutableArrayList create(E[] elems) { return new ImmutableArrayList(elems); } + + public ImmutableArrayList create(Collection elems) { + return new ImmutableArrayList(elems); + } + /** *

Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's @@ -127,7 +125,6 @@ public int size() { return _length; } - public E get(int index) { if (index < 0 || index >= size()) throw new IndexOutOfBoundsException(); @@ -137,25 +134,15 @@ public E get(int index) { return null; } - public int indexOf(E elem) { - int i = 0; - for (E other : this) - if (equals(elem, other)) - return i; - else - ++i; - return -1; - } - @Override - public ImmutableList subList(int fromIndex, int toIndex) + public ImmutableArrayList subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException, IllegalArgumentException { if (fromIndex < 0 || toIndex > size()) throw new IndexOutOfBoundsException(); if (fromIndex > toIndex) throw new IllegalArgumentException(); if (fromIndex == toIndex) - return new ImmutableLinkedList(); + return new ImmutableArrayList(); int j = 0; @SuppressWarnings("unchecked") @@ -168,161 +155,13 @@ public ImmutableList subList(int fromIndex, int toIndex) return new ImmutableArrayList(res); } - @Override - public ImmutableList reverse() { + public ImmutableArrayList reverse() { return new ImmutableReversedArrayList(this); } - - public ImmutableList sort(Comparator comparator) { - E[] a = toArray(); - Arrays.sort(a,(Comparator) comparator); - return new ImmutableLinkedList(a); - } - - public boolean contains(E elem) { - return any((E other) -> equals(elem, other)); - } - - public boolean containsAll(Collection elems) { - return containsAll(new ImmutableArrayList(elems)); - } - - public boolean containsAll(ImmutableList elems) { - return elems.all((E elem) -> contains(elem)); - } - @SuppressWarnings("unchecked") - public boolean containsAll(E... elems) { - return containsAll(new ImmutableArrayList(elems)); - } - - - public boolean any(Predicate predicate) { - for (E elem : this) - if (predicate.test(elem)) - return true; - return false; - } - - - public boolean all(Predicate predicate) { - for (E elem : this) - if (!predicate.test(elem)) - return false; - return true; - } - - - public ImmutableList cons(E elem) { - @SuppressWarnings("unchecked") - E[] elems = (E[]) new Object[size()+1]; - elems[0] = elem; - - int i = 1; - for (E e : this) { - elems[i] = e; - ++i; - } - - return new ImmutableArrayList(elems); - } - - - public ImmutableList concat(Collection elems) { - ImmutableList list = this; - for (E elem: elems){ - list = list.concat(elem); - } - return list; - } - - - public ImmutableList concat(ImmutableList elems) { - ImmutableList list = this; - for (E elem : elems) { - list = list.concat(elem); - } - return list; - } - - @SuppressWarnings({"unchecked"}) - public ImmutableList concat(E... elems){ - ImmutableList list = this; - for (int i = 0 ; i concat(E elem) { - @SuppressWarnings("unchecked") - E[] elems = (E[]) new Object[size() + 1]; - int i = 0; - for (E e : this) { - elems[i] = e; - ++i; - } - elems[size()] = elem; - return new ImmutableLinkedList(elems); - } - - - public ImmutableList remove(Collection elems) { - ImmutableList list = this; - for (E elem: elems){ - list = list.remove(elem); - } - return list; - } - - - public ImmutableList remove(ImmutableList elems) { - ImmutableList list = this; - for (E elem : elems) { - list = list.remove(elem); - } - return list; - } - - @SuppressWarnings("unchecked") - public ImmutableList remove(E... elems) { - ImmutableList list = this; - for (int i = 0 ; i remove(E elem) { - E[] newElems; - int i; - boolean remove; - newElems = (E[]) new Object[size() - 1]; - i = 0; - remove = false; - for ( E e :this){ - if(!remove && equals(elem,e)) - remove = true; - else{ - if (i == this.size()-1) - throw new IllegalArgumentException(); - newElems[i] = e; - i++; - } - } - - - return new ImmutableLinkedList(newElems); - } - - - @SuppressWarnings("unchecked") - public ImmutableList remove(int index) { //TODO + public ImmutableArrayList remove(int index) { E[] newElems; int i; boolean remove; @@ -341,167 +180,37 @@ public ImmutableList remove(int index) { //TODO ++i; } } - return new ImmutableLinkedList(newElems); - } - - - public ImmutableList union(Collection elems) { - // TODO Auto-generated method stub - return null; - } - - - public ImmutableList union(ImmutableList elems) { - // TODO Auto-generated method stub - return null; - } - - @SuppressWarnings("unchecked") - public ImmutableList union(E... elems) { - // TODO Auto-generated method stub - return null; + return new ImmutableArrayList(newElems); } - - public ImmutableList intersect(Collection elems) { - // TODO Auto-generated method stub - return null; - } - - - public ImmutableList intersect(ImmutableList elems) { - // TODO Auto-generated method stub - return null; - } - - - @SuppressWarnings("unchecked") - public ImmutableList intersect(E... elems) { - // TODO Auto-generated method stub - return null; + public E[] toArray() { + return getArray(); } - - public ImmutableList map(Function mapper) { + public ImmutableArrayList cons(E elem) { @SuppressWarnings("unchecked") - F[] elems = (F[]) new Object[size()]; - int i = 0; - for (E elem : this) { - elems[i] = mapper.apply(elem); + E[] elems = (E[]) new Object[size()+1]; + elems[0] = elem; + + int i = 1; + for (E e : this) { + elems[i] = e; ++i; } - return new ImmutableArrayList(elems); - } - - - @Override - public ImmutableList filter(Predicate predicate) { - ImmutableList res = new ImmutableArrayList(); - for (E elem : this) - if (predicate.test(elem)) - res = res.concat(elem); - return res; - } - - - - public Optional reduce(BinaryOperator accumulator) { - switch (size()) { - case 0 : return Optional.empty(); - case 1 : return Optional.of(get(0)); - default : - - E result = get(0); - for (E elem : subList(1, size())) { - result = accumulator.apply(result, elem); - } - return Optional.of(result); - } + return new ImmutableArrayList(elems); } - /** - * Hash an object. - * - * @param o the object to hash - * @return o1 == null ? 0 : o1.hashCode() - */ - static final int hashCode(Object o) { - return o == null ? 0 : o.hashCode(); - } public int hashCode() { - int hashCode = 1; - Iterator itr = iterator(); - int pos = size(); - while (--pos >= 0) - hashCode = 31 * hashCode + hashCode(itr.next()); - return hashCode; - } - - public E[] toArray() { - return getArray(); - } - - @SuppressWarnings("hiding") - @Override - public E[] toArray(E[] a) { - return a; - } - - public List asList() { - List al = new ArrayList(size()); - for(E e : this) - al.add(e); - return al; + return ImmutableList.hashCode(this); } - /** - * Compare two objects according to Collection semantics. - * - * @param o1 the first object - * @param o2 the second object - * @return o1 == null ? o2 == null : o1.equals(o2) - */ - static final boolean equals(Object o1, Object o2) { - return o1 == null ? o2 == null : o1.equals(o2); + public InductiveIterativeList clone() { + return InductiveIterativeList.clone(this); } public boolean equals(Object o) { - if (! (o instanceof ImmutableList)) - return false; - - @SuppressWarnings("rawtypes") - ImmutableList other = (ImmutableList) o; - - if (size() != other.size()) - return false; - - Iterator it1 = iterator(); - @SuppressWarnings("rawtypes") - Iterator it2 = other.iterator(); - - while (it1.hasNext()) { - if (!equals(it1.next(), it2.next())) - return false; - } - - return true; - } - - public E head() throws NoSuchElementException { - return null; - } - - public ImmutableList tail() throws UnsupportedOperationException { - return null; - } - - public E last() throws NoSuchElementException { - return null; - } - - public ImmutableList clone() { - return subList(0, size()); + return IterativeList.equals(this, o); } } diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java index 8a666d1..10d29a9 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java @@ -1,21 +1,11 @@ package collections.implementations; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; import java.util.Iterator; -import java.util.List; import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.function.BinaryOperator; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; +import collections.interfaces.InductiveIterativeList; +import collections.interfaces.IterativeList; import collections.interfaces.ImmutableList; class Node { @@ -61,7 +51,7 @@ public boolean hasNext() { } } -public class ImmutableLinkedList implements ImmutableList { +public class ImmutableLinkedList implements InductiveIterativeList { /** The first node element of the list. */ private final Node head; @@ -123,7 +113,7 @@ public ImmutableLinkedList() { * @throws NullPointerException if elems is null */ @SuppressWarnings("unchecked") - public ImmutableLinkedList(Collection elems) { + public ImmutableLinkedList(Collection elems) { this((E[])elems.toArray()); } @@ -138,6 +128,13 @@ public ImmutableLinkedList(E... elems) { if (elems == null) throw new NullPointerException(); + if (elems.length == 0) { + this.head = null; + this.last = null; + this.size = 0; + return; + } + Node head = new Node(elems[elems.length - 1]); this.last = head; @@ -148,10 +145,14 @@ public ImmutableLinkedList(E... elems) { this.size = elems.length; } - public ImmutableList create(E[] elems) { + public ImmutableLinkedList create(E[] elems) { return new ImmutableLinkedList(elems); } + public ImmutableLinkedList create(Collection elems) { + return new ImmutableLinkedList(elems); + } + // Operations public E get(int index) throws IndexOutOfBoundsException { @@ -168,16 +169,6 @@ public E get(int index) throws IndexOutOfBoundsException { return null; // Never happens } - public int indexOf(E elem) { - int i = 0; - for (E other : this) - if (equals(elem, other)) - return i; - else - ++i; - return -1; - } - public E head() throws NoSuchElementException { if (isEmpty()) throw new NoSuchElementException(); @@ -185,13 +176,6 @@ public E head() throws NoSuchElementException { return headNode().getElement(); } - public ImmutableList tail() throws UnsupportedOperationException { - if (isEmpty()) - throw new UnsupportedOperationException(); - else - return subList(1, size()); - } - public E last() throws NoSuchElementException { if (isEmpty()) throw new NoSuchElementException(); @@ -200,7 +184,7 @@ public E last() throws NoSuchElementException { } @SuppressWarnings("unchecked") - public ImmutableList subList(int fromIndex, int toIndex) throws + public ImmutableLinkedList subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException, IllegalArgumentException { @@ -230,137 +214,16 @@ public ImmutableList subList(int fromIndex, int toIndex) throws toIndex - fromIndex); } - public ImmutableList reverse() { - if (isEmpty()) - return this; - else - return tail().reverse().concat(head()); - } - - public boolean contains(E elem) { - return any((E other) -> equals(elem, other)); - } - - public boolean containsAll(Collection elems) { - return containsAll(new ImmutableLinkedList(elems)); - } - - public boolean containsAll(ImmutableList elems) { - return elems.all((E elem) -> contains(elem)); - } - - public @SuppressWarnings({"unchecked"}) - boolean containsAll(E... elems) { - return containsAll(new ImmutableLinkedList(elems)); - } - - public boolean any(Predicate predicate) { - for (E elem : this) - if (predicate.test(elem)) - return true; - return false; - } - - public boolean all(Predicate predicate) { - for (E elem : this) - if (!predicate.test(elem)) - return false; - return true; - } - // Factories - public ImmutableList cons(E elem) { + public ImmutableLinkedList cons(E elem) { return new ImmutableLinkedList(new Node(elem, headNode()), lastNode(), size() + 1); } - public ImmutableList concat(Collection elems){ - ImmutableList list = this; - for (E elem: elems) { - list = list.concat(elem); - } - return list; - } - public ImmutableList concat(ImmutableList elems) { - ImmutableList list = this; - for (E elem : elems) { - list = list.concat(elem); - } - return list; - } - @SuppressWarnings({"unchecked"}) - public ImmutableList concat(E... elems){ - ImmutableList list = this; - for (int i = 0 ; i concat(E elem) { - E[] elems = (E[]) new Object[size() + 1]; - int i = 0; - for (E e : this) { - elems[i] = e; - ++i; - } - elems[size()] = elem; - return new ImmutableLinkedList(elems); - } - - public ImmutableList remove(Collection elems) { - ImmutableList list = this; - for (E elem: elems) { - list = list.remove(elem); - } - return list; - - } - - public ImmutableList remove(ImmutableList elems) { - ImmutableList list = this; - for (E elem : elems) { - list = list.remove(elem); - } - return list; - } - - @SuppressWarnings({"unchecked"}) - public ImmutableList remove(E... elems) { - ImmutableList list = this; - for (int i = 0 ; i < elems.length ; ++i) { - list = list.remove(elems[i]); - } - return list; - } - - @SuppressWarnings("unchecked") - public ImmutableList remove(E elem) { - E[] newElems; - int i; - boolean remove; - newElems = (E[]) new Object[size() - 1]; - i = 0; - remove = false; - for ( E e :this){ - if(!remove && equals(elem,e)) - remove = true; - else{ - if (i == this.size()-1) - throw new IllegalArgumentException(); - newElems[i] = e; - i++; - } - } - - return new ImmutableLinkedList(newElems); - } - @SuppressWarnings("unchecked") - public ImmutableList remove(int index) { + public ImmutableLinkedList remove(int index) { E[] newElems; int i; boolean remove; @@ -371,7 +234,7 @@ public ImmutableList remove(int index) { newElems = (E[]) new Object[size() -1]; i = 0; remove = false; - for ( E e :this){ + for ( E e : this){ if(!remove && i==index) remove = true; else{ @@ -382,40 +245,6 @@ public ImmutableList remove(int index) { return new ImmutableLinkedList(newElems); } - @SuppressWarnings("unchecked") - public ImmutableList map(Function mapper) { - F[] elems = (F[]) new Object[size()]; - int i = 0; - for (E elem : this) { - elems[i] = mapper.apply(elem); - ++i; - } - - return new ImmutableLinkedList(elems); - } - - public ImmutableList filter(Predicate predicate) { - ImmutableList res = new ImmutableLinkedList(); - for (E elem : this) - if (predicate.test(elem)) - res = res.concat(elem); - return res; - } - - public Optional reduce(BinaryOperator accumulator) { - switch (size()) { - case 0 : return Optional.empty(); - case 1 : return Optional.of(head()); - default : - - E result = head(); - for (E elem : tail()) { - result = accumulator.apply(result, elem); - } - return Optional.of(result); - } - } - // Iterators & streams class ImmutableLinkedListIterator implements Iterator { @@ -461,87 +290,15 @@ public Iterator iterator() { return new ImmutableLinkedListIterator(); } - public boolean equals(Object o) { - if (! (o instanceof ImmutableList)) - return false; - - @SuppressWarnings("rawtypes") - ImmutableList other = (ImmutableList) o; - - if (size() != other.size()) - return false; - - Iterator it1 = iterator(); - @SuppressWarnings("rawtypes") - Iterator it2 = other.iterator(); - - while (it1.hasNext()) { - if (!equals(it1.next(), it2.next())) - return false; - } - - return true; - } - - /** - * Compare two objects according to Collection semantics. - * - * @param o1 the first object - * @param o2 the second object - * @return o1 == null ? o2 == null : o1.equals(o2) - */ - static boolean equals(Object o1, Object o2) { - return o1 == null ? o2 == null : o1.equals(o2); - } - - /** - * Hash an object. - * - * @param o the object to hash - * @return o1 == null ? 0 : o1.hashCode() - */ - static int hashCode(Object o) { - return o == null ? 0 : o.hashCode(); - } - public int hashCode() { - int hashCode = 1; - Iterator itr = iterator(); - int pos = size(); - while (--pos >= 0) - hashCode = 31 * hashCode + hashCode(itr.next()); - return hashCode; - } - - // Conversions - @SuppressWarnings("unchecked") - public E[] toArray(){ - return toArray((E[]) new Object[size()]); - } - - @SuppressWarnings({ "unchecked", "hiding" }) - public E[] toArray(E[] a){ - int i; - E[] result; - i=0; - result = a ; - for (Node x = (Node) this.head; x != null; x = x.getNext()){ - result[i++] = x.getElement(); - } - return a; + return ImmutableList.hashCode(this); } - public List asList(){ - List myList = new ArrayList(); - - for (E e : this){ - myList.add(e); - } - return myList; + public InductiveIterativeList clone() { + return InductiveIterativeList.clone(this); } - public ImmutableList clone() { - return subList(0, size()); + public boolean equals(Object o) { + return IterativeList.equals(this, o); } - } diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java index eee1f88..38feff9 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java @@ -5,8 +5,6 @@ import java.util.Iterator; import java.util.NoSuchElementException; -import collections.interfaces.ImmutableList; - public class ImmutableReversedArrayList extends ImmutableArrayList { /** The encapsulated list we delegate things to. */ @@ -55,7 +53,7 @@ public E last() throws NoSuchElementException { } @SuppressWarnings("unchecked") - public ImmutableList subList(int fromIndex, int toIndex) throws + public ImmutableArrayList subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException, IllegalArgumentException { if (fromIndex == toIndex) @@ -65,12 +63,12 @@ public ImmutableList subList(int fromIndex, int toIndex) throws reverseIndex(fromIndex-1)).reverse(); } - public ImmutableList reverse() { + public ImmutableArrayList reverse() { return list; } @SuppressWarnings("unchecked") - public ImmutableList remove(int index) { + public ImmutableArrayList remove(int index) { return list.remove(reverseIndex(index)).reverse(); } diff --git a/Immutable_collections_java8_project/src/collections/interfaces/ImmutableList.java b/Immutable_collections_java8_project/src/collections/interfaces/ImmutableList.java index b2527d1..03d9e94 100644 --- a/Immutable_collections_java8_project/src/collections/interfaces/ImmutableList.java +++ b/Immutable_collections_java8_project/src/collections/interfaces/ImmutableList.java @@ -9,6 +9,7 @@ import java.util.Comparator; import java.util.Iterator; import java.util.List; +import java.util.ArrayList; import java.util.Optional; import java.util.Spliterator; import java.util.Spliterators; @@ -18,58 +19,27 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; -public interface ImmutableList extends InductiveList, - IterativeList, - Iterable, +public interface ImmutableList extends Iterable, Cloneable { - ImmutableList create(E[] elems); + public ImmutableList create(E[] elems); + public ImmutableList create(Collection elems); /** * Returns true if this list contains no elements. * * @returns true if this list contains no elements */ - default boolean isEmpty() { - return size() == 0; - } - - /** - * Returns the number of elements in this list. - * - * @returns the number of elements in this list - **/ - int size(); - - /** - * Returns a portion of this list. - * - * @param fromIndex low endpoint (inclusive) of the subList - * @param toIndex high endpoint (exclusive) of the subList - * @returns a portion of this list - * @throws IndexOutOfBoundsException if an endpoint index value is out - * of range (fromIndex < 0 || toIndex > size) - * @throws IllegalArgumentException if the endpoint indices are out of - * order (fromIndex > toIndex) - */ - ImmutableList subList(int fromIndex, int toIndex) throws - IndexOutOfBoundsException, - IllegalArgumentException; // Java && Guava - - /** - * Returns a new list with the elements of this list in reverse order. - * - * @return a new list with the elements of this list in reverse order. - */ - ImmutableList reverse(); // Guava: reverse + boolean isEmpty(); /** * Sorts this list using the supplied Comparator to compare elements. * @param comparator * @return the list */ - default ImmutableList sort(Comparator comparator) { // Java: sort, Scala: sorted/sortWith - E[] a = toArray(); + default ImmutableList sort(Comparator comparator) { + @SuppressWarnings({"unchecked"}) + E[] a = (E[]) toArray(); Arrays.sort(a, comparator); return create(a); } @@ -82,7 +52,12 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @returns true if predicate is satisfied by at least one element of * the list. */ - boolean any(Predicate predicate); // Scala: exists/find + default boolean any(Predicate predicate) { + for (E elem : this) + if (predicate.test(elem)) + return true; + return false; + } /** * Returns whether given predicate is satisfied by all elements of the @@ -91,101 +66,41 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @param predicate The predicate to be tested on elements of the list. * @returns true if predicate is satified by all elements of the list. */ - boolean all(Predicate predicate); // Scala: forall - - /** - * Returns a new list containing the elements from this list followed by - * the elements from the given list. - * - * @param elems the list to be concatened with - * @returns a new list containing the elements from this list followed - * by the elements from the given list - */ - ImmutableList concat(Collection elems); - - /** - * Returns a new list containing the elements from this list followed by - * the elements from the given list. - * - * @param elems the list to be concatened with - * @returns a new list containing the elements from this list followed - * by the elements from the given list - */ - ImmutableList concat(ImmutableList elems); - - /** - * Returns a new list containing the elements from this list followed by - * the elements from the given list. - * - * @param elems the list to be concatened with - * @returns a new list containing the elements from this list followed - * by the elements from the given list - */ - @SuppressWarnings({"unchecked"}) - ImmutableList concat(E... elems); - - /** - * Returns a new list containing the elements from this list followed by - * the elements from the given list. - * - * @param elem the list to be concatened with - * @returns a new list containing the elements from this list followed - * by the elements from the given list - */ - ImmutableList concat(E elem); - - /** - * Returns a new list without all the elements of the specified - * elements from this list. - * - * @param elems - elements to be removed from this list, if present - * @return a new list without all the elements of the specified - * elements from this list - */ - ImmutableList remove(ImmutableList elems); - - /** - * Returns a new list without all the elements of the specified - * elements from this list. - * - * @param elems - elements to be removed from this list, if present - * @return a new list without all the elements of the specified - * elements from this list - */ - ImmutableList remove(Collection elems); - - /** - * Returns a new list without all the element of the specified elements - * from this list - * - * @param elems - elements to be removed from this list, if present - * @return a new list without all the element of the specified elements - * from this list - */ - @SuppressWarnings({"unchecked"}) - ImmutableList remove(E... elems); - - /** - * Returns a new list without the first occurrence of the specified - * element from this list. - * - * @param elem - element to be removed from this list, if present - * @return a new list without the first occurrence of the specified - * element from this list - */ - ImmutableList remove(E elem) throws IllegalArgumentException; + default boolean all(Predicate predicate) { + for (E elem : this) + if (!predicate.test(elem)) + return false; + return true; + } /** - * Returns a new list without the element at the specified position in - * this list. + * Returns the first index where the element is located in the list, or -1. * - * @param index - the index of the element to be removed - * @return a new list without the element at the specified position in - * this list + * @param o the element to look for + * @return its position, or -1 if not found */ - ImmutableList remove(int index) throws ArrayIndexOutOfBoundsException; - - /** + default int indexOf(E elem) { + int i = 0; + for (E other : this) + if (equals(elem, other)) + return i; + else + ++i; + return -1; + } + + /** + * Compare two objects according to Collection semantics. + * + * @param o1 the first object + * @param o2 the second object + * @return o1 == null ? o2 == null : o1.equals(o2) + */ + static boolean equals(Object o1, Object o2) { + return o1 == null ? o2 == null : o1.equals(o2); + } + + /** * Returns true if this list contains the specified element. More formally, * returns true if and only if this list contains at least one element e * such that (o==null ? e==null : o.equals(e)). @@ -193,7 +108,9 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @param elem the element to look for * @return true if it is found */ - boolean contains(E elem); // Scala, Java, Guava + default boolean contains(E elem) { + return any((E other) -> equals(elem, other)); + } /** * Returns true if this list contains all of the elements of the @@ -203,7 +120,9 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @return true if this list contains all of the elements of the * specified collection */ - boolean containsAll(Collection elems); + default boolean containsAll(Collection elems) { + return containsAll(create(elems)); + } /** * Returns true if this list contains all of the elements of the @@ -213,7 +132,9 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @return true if this list contains all of the elements of the * specified list */ - boolean containsAll(ImmutableList elems); + default boolean containsAll(ImmutableList elems) { + return elems.all((E elem) -> contains(elem)); + } /** * Returns true if this list contains all of the given elements @@ -222,7 +143,9 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @return true if this list contains all of the given elements */ @SuppressWarnings({"unchecked"}) - boolean containsAll(E... elems); + default boolean containsAll(E... elems) { + return containsAll(create(elems)); + } /** * Returns a new list consisting of the results of applying the given @@ -231,7 +154,13 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @param mapper a function to apply to each element * @returns the new list */ - ImmutableList map(Function mapper); // Scala: map + default ImmutableList map(Function mapper) { + List elems = new ArrayList(); + for (E elem : this) { + elems.add(mapper.apply(elem)); + } + return create(elems); + } /** * Returns a list consisting of the elements of this list that match the @@ -241,7 +170,13 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @return a list consisting of the elements of this list that match the * given predicate. */ - ImmutableList filter(Predicate predicate); // Scala: filter + default ImmutableList filter(Predicate predicate) { + ArrayList list = new ArrayList(); + for (E elem : this) + if (predicate.test(elem)) + list.add(elem); + return create(list); + } /** * Performs a reduction on the elements of this list, using an associative @@ -252,15 +187,21 @@ default ImmutableList sort(Comparator comparator) { // Java: sort, * @return an Optional describing the result of the reduction * @throws NullPointerException - if the result of the reduction is null */ - Optional reduce(BinaryOperator accumulator); // Scala: reduce + default Optional reduce(BinaryOperator accumulator) { + Iterator it = iterator(); + if (!it.hasNext()) + return Optional.empty(); + + E result = it.next(); + while (it.hasNext()) + result = accumulator.apply(result, it.next()); + return Optional.of(result); + } default Spliterator spliterator() { - return Spliterators.spliterator(iterator(), - size(), + return Spliterators.spliteratorUnknownSize(iterator(), Spliterator.IMMUTABLE | - Spliterator.ORDERED | - Spliterator.SIZED | - Spliterator.SUBSIZED); + Spliterator.ORDERED); } /** @@ -281,21 +222,6 @@ default Stream parallelStream() { return StreamSupport.stream(spliterator(), true); } - /** - * Compares the specified object with this list for equality. Returns true - * if and only if the specified object is also a list, both lists have the - * same size, and all corresponding pairs of elements in the two lists are - * equal. (Two elements e1 and e2 are equal if - * (e1==null ? e2==null : e1.equals(e2)).) In other words, two - * lists are defined to be equal if they contain the same elements in the - * same order. This definition ensures that the equals method works properly - * across different implementations of the ImmutableList interface. - * - * @param o the object to be compared for equality with this list - * @return if the specified object is equal to this list - */ - boolean equals(Object o); - /** * Returns an array containing all of the elements in this list in * proper sequence (from first to last element). @@ -309,7 +235,13 @@ default Stream parallelStream() { * @return an array containing all of the elements in this list in * proper sequence */ - E[] toArray(); // Scala && Java: toArray + @SuppressWarnings({ "unchecked"}) + default E[] toArray() { + int size = 0; + for (E elem : this) + ++size; + return toArray((E[]) new Object[size]); + } /** * Returns an array containing all of the elements in this list in @@ -341,7 +273,15 @@ default Stream parallelStream() { * runtime type is allocated for this purpose. * @return an array containing the elements of the list */ - E[] toArray(E[] a); + @SuppressWarnings({ "unchecked", "hiding" }) + default E[] toArray(E[] a) { + int i = 0; + for (E elem : this) { + a[i] = elem; + ++i; + } + return a; + } /** * Returns a list containing all of the elements in this list in proper @@ -350,8 +290,78 @@ default Stream parallelStream() { * @return a list containing all of the elements in this list in proper * sequence */ - List asList(); // Scala: toList, Guava: asList + default List asList() { + List myList = new ArrayList(); + for (E e : this){ + myList.add(e); + } + return myList; + } + + public ImmutableList clone(); + + // To be used for the clone() method in concrete classes (since Object + // methods cannot be overriden with the default keyword) + static ImmutableList clone(ImmutableList list) { + return list.create(list.asList()); + } - ImmutableList clone(); + /** + * Compares the specified object with this list for equality. Returns true + * if and only if the specified object is also a list, both lists have the + * same size, and all corresponding pairs of elements in the two lists are + * equal. (Two elements e1 and e2 are equal if + * (e1==null ? e2==null : e1.equals(e2)).) In other words, two + * lists are defined to be equal if they contain the same elements in the + * same order. This definition ensures that the equals method works properly + * across different implementations of the ImmutableList interface. + * + * @param o the object to be compared for equality with this list + * @return if the specified object is equal to this list + */ + boolean equals(Object o); + // To be used for the equals() method in concrete classes (since Object + // methods cannot be overriden with the default keyword) + static boolean equals(ImmutableList list, Object o) { + if (! (o instanceof ImmutableList)) + return false; + + @SuppressWarnings("rawtypes") + ImmutableList other = (ImmutableList) o; + + Iterator it1 = list.iterator(); + @SuppressWarnings("rawtypes") Iterator it2 = other.iterator(); + + while (it1.hasNext() && it2.hasNext()) { + if (!equals(it1.next(), it2.next())) + return false; + } + if (it1.hasNext() || it2.hasNext()) + return false; + + return true; + } + + /** + * Hash an object. + * + * @param o the object to hash + * @return o1 == null ? 0 : o1.hashCode() + */ + static int hashCode(Object o) { + return o == null ? 0 : o.hashCode(); + } + + public int hashCode(); + + // To be used for the hashCode() method in concrete classes (since Object + // methods cannot be overriden with the default keyword) + static int hashCode(ImmutableList list) { + int hashCode = 1; + Iterator itr = list.iterator(); + while (itr.hasNext()) + hashCode = 31 * hashCode + hashCode(itr.next()); + return hashCode; + } } diff --git a/Immutable_collections_java8_project/src/collections/interfaces/InductiveIterativeList.java b/Immutable_collections_java8_project/src/collections/interfaces/InductiveIterativeList.java new file mode 100644 index 0000000..357d48f --- /dev/null +++ b/Immutable_collections_java8_project/src/collections/interfaces/InductiveIterativeList.java @@ -0,0 +1,235 @@ +package collections.interfaces; + +import java.util.Collection; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.NoSuchElementException; + +public interface InductiveIterativeList extends InductiveList, + IterativeList { + + public InductiveIterativeList create(E[] elems); + + /** + * Returns a portion of this list. + * + * @param fromIndex low endpoint (inclusive) of the subList + * @param toIndex high endpoint (exclusive) of the subList + * @returns a portion of this list + * @throws IndexOutOfBoundsException if an endpoint index value is out + * of range (fromIndex < 0 || toIndex > size) + * @throws IllegalArgumentException if the endpoint indices are out of + * order (fromIndex > toIndex) + */ + InductiveIterativeList subList(int fromIndex, int toIndex) throws + IndexOutOfBoundsException, + IllegalArgumentException; + + /** + * Returns a new list with the elements of this list in reverse order. + * + * @return a new list with the elements of this list in reverse order. + */ + default InductiveIterativeList reverse() { + if (isEmpty()) + return this; + else + return tail().reverse().concat(head()); + } + + /** + * Returns a new list containing the elements from this list followed by + * the elements from the given list. + * + * @param elems the list to be concatened with + * @returns a new list containing the elements from this list followed + * by the elements from the given list + */ + default InductiveIterativeList concat(Collection elems) { + InductiveIterativeList list = this; + for (E elem : elems){ + list = list.concat(elem); + } + return list; + } + + /** + * Returns a new list containing the elements from this list followed by + * the elements from the given list. + * + * @param elems the list to be concatened with + * @returns a new list containing the elements from this list followed + * by the elements from the given list + */ + default InductiveIterativeList concat(InductiveIterativeList elems) { + InductiveIterativeList list = this; + for (E elem : elems){ + list = list.concat(elem); + } + return list; + } + + /** + * Returns a new list containing the elements from this list followed by + * the elements from the given list. + * + * @param elems the list to be concatened with + * @returns a new list containing the elements from this list followed + * by the elements from the given list + */ + @SuppressWarnings({"unchecked"}) + default InductiveIterativeList concat(E... elems) { + InductiveIterativeList list = this; + for (int i = 0 ; i concat(E elem) { + @SuppressWarnings("unchecked") + E[] elems = (E[]) new Object[size() + 1]; + int i = 0; + for (E e : this) { + elems[i] = e; + ++i; + } + elems[size()] = elem; + return create(elems); + } + + /** + * Returns a new list without all the elements of the specified + * elements from this list. + * + * @param elems - elements to be removed from this list, if present + * @return a new list without all the elements of the specified + * elements from this list + */ + default InductiveIterativeList remove(InductiveIterativeList elems) { + InductiveIterativeList list = this; + for (E elem : elems) { + list = list.remove(elem); + } + return list; + } + + /** + * Returns a new list without all the elements of the specified + * elements from this list. + * + * @param elems - elements to be removed from this list, if present + * @return a new list without all the elements of the specified + * elements from this list + */ + default InductiveIterativeList remove(Collection elems) { + InductiveIterativeList list = this; + for (E elem : elems) { + list = list.remove(elem); + } + return list; + } + + /** + * Returns a new list without all the element of the specified elements + * from this list + * + * @param elems - elements to be removed from this list, if present + * @return a new list without all the element of the specified elements + * from this list + */ + @SuppressWarnings({"unchecked"}) + default InductiveIterativeList remove(E... elems) { + InductiveIterativeList list = this; + for (int i = 0 ; i remove(E elem) throws IllegalArgumentException { + E[] newElems; + int i; + boolean remove; + newElems = (E[]) new Object[size() - 1]; + i = 0; + remove = false; + for (E e : this) { + if(!remove && ImmutableList.equals(elem, e)) + remove = true; + else{ + if (i == this.size()-1) + throw new IllegalArgumentException(); + newElems[i] = e; + i++; + } + } + + return create(newElems); + } + + /** + * Returns a new list without the element at the specified position in + * this list. + * + * @param index - the index of the element to be removed + * @return a new list without the element at the specified position in + * this list + */ + InductiveIterativeList remove(int index) throws ArrayIndexOutOfBoundsException; + + // To be used for the clone() method in concrete classes (since Object + // methods cannot be overriden with the default keyword) + static InductiveIterativeList clone(InductiveIterativeList list) { + return list.subList(0, list.size()); + } + + default InductiveIterativeList tail() throws UnsupportedOperationException { + if (isEmpty()) + throw new UnsupportedOperationException(); + else + return subList(1, size()); + } + + + default E head() throws NoSuchElementException { + if (isEmpty()) + throw new NoSuchElementException(); + else + return get(0); + } + + default E last() throws NoSuchElementException { + if (isEmpty()) + throw new NoSuchElementException(); + else + return get(size()-1); + } + + default InductiveIterativeList map(Function mapper) { + return (InductiveIterativeList) InductiveList.super.map(mapper); + } + + default InductiveIterativeList filter(Predicate predicate) { + return (InductiveIterativeList) InductiveList.super.filter(predicate); + } + + InductiveIterativeList cons(E elem); +} diff --git a/Immutable_collections_java8_project/src/collections/interfaces/InductiveList.java b/Immutable_collections_java8_project/src/collections/interfaces/InductiveList.java index ab7712e..5127781 100644 --- a/Immutable_collections_java8_project/src/collections/interfaces/InductiveList.java +++ b/Immutable_collections_java8_project/src/collections/interfaces/InductiveList.java @@ -1,8 +1,10 @@ package collections.interfaces; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.NoSuchElementException; -public interface InductiveList { +public interface InductiveList extends ImmutableList { /** * Return a new list with the elements of this list appended to given element. @@ -10,7 +12,7 @@ public interface InductiveList { * @param elem The first element of the new list * @return a new list with the elements of this list appended to given element. */ - ImmutableList cons(E elem); // Scala: + operator + InductiveList cons(E elem); /** * Returns the first element in the list. @@ -26,7 +28,7 @@ public interface InductiveList { * @returns a list with all elements of this list except the first one * @throws UnsupportedOperationException if this list is empty */ - ImmutableList tail() throws UnsupportedOperationException; + InductiveList tail() throws UnsupportedOperationException; /** * Returns the last element of the list. @@ -35,4 +37,12 @@ public interface InductiveList { * @throws NoSuchElementException if the list is empty */ E last() throws NoSuchElementException; + + default InductiveList map(Function mapper) { + return (InductiveList) ImmutableList.super.map(mapper); + } + + default InductiveList filter(Predicate predicate) { + return (InductiveList) ImmutableList.super.filter(predicate); + } } diff --git a/Immutable_collections_java8_project/src/collections/interfaces/IterativeList.java b/Immutable_collections_java8_project/src/collections/interfaces/IterativeList.java index cfd29cf..0508006 100644 --- a/Immutable_collections_java8_project/src/collections/interfaces/IterativeList.java +++ b/Immutable_collections_java8_project/src/collections/interfaces/IterativeList.java @@ -1,6 +1,23 @@ package collections.interfaces; -public interface IterativeList { +import java.util.Spliterators; +import java.util.Spliterator; +import java.util.Iterator; +import java.util.function.Function; +import java.util.function.Predicate; + +public interface IterativeList extends ImmutableList { + + default boolean isEmpty() { + return size() == 0; + } + + /** + * Returns the number of elements in this list. + * + * @returns the number of elements in this list + **/ + int size(); /** * Returns the element at the specified position in this list. @@ -10,12 +27,54 @@ public interface IterativeList { */ E get(int index) throws IndexOutOfBoundsException; - /** - * Returns the first index where the element is located in the list, or -1. - * - * @param o the element to look for - * @return its position, or -1 if not found - */ - int indexOf(E elem); + default Spliterator spliterator() { + return Spliterators.spliterator(iterator(), + size(), + Spliterator.IMMUTABLE | + Spliterator.ORDERED | + Spliterator.SIZED | + Spliterator.SUBSIZED); + } + + public boolean equals(Object o); + + // To be used for the equals() method in concrete classes (since Object + // methods cannot be overriden with the default keyword) + static boolean equals(IterativeList list, Object o) { + if (o instanceof IterativeList) + return list.equals((IterativeList)o); + else if (o instanceof ImmutableList) + return ImmutableList.equals(list, o); + else + return false; + } + + default public boolean equals(IterativeList other) { + if (size() != other.size()) + return false; + + Iterator it1 = iterator(); + @SuppressWarnings("rawtypes") + Iterator it2 = other.iterator(); + + while (it1.hasNext()) { + if (!ImmutableList.equals(it1.next(), it2.next())) + return false; + } + + return true; + } + + @SuppressWarnings({ "unchecked"}) + default E[] toArray() { + return toArray((E[]) new Object[size()]); + } + + default IterativeList map(Function mapper) { + return (IterativeList) ImmutableList.super.map(mapper); + } + default IterativeList filter(Predicate predicate) { + return (IterativeList) ImmutableList.super.filter(predicate); + } } diff --git a/Immutable_collections_java8_project/src/main/Benchmarks.java b/Immutable_collections_java8_project/src/main/Benchmarks.java index c74790f..cdc3db8 100644 --- a/Immutable_collections_java8_project/src/main/Benchmarks.java +++ b/Immutable_collections_java8_project/src/main/Benchmarks.java @@ -2,12 +2,12 @@ import collections.implementations.ImmutableArrayList; import collections.implementations.ImmutableLinkedList; -import collections.interfaces.ImmutableList; +import collections.interfaces.InductiveIterativeList; public class Benchmarks { - ImmutableList ll; - ImmutableList al; + InductiveIterativeList ll; + InductiveIterativeList al; public Benchmarks() { @@ -29,7 +29,7 @@ public void runLinkedListBench(int warmup, int maxIterations) long end = 0; int indicetoGet = ll.size()-1; Integer x; - ImmutableList out ; + InductiveIterativeList out ; System.out.println("ImmutableLinkedList Microbenchs started..."); @@ -87,7 +87,7 @@ public void runArrayListBench(int warmup, int maxIterations) long end = 0; int indicetoGet = al.size()-1; Integer x = new Integer(0); - ImmutableList out ; + InductiveIterativeList out ; System.out.println("ImmutableArrayList Microbenchs started..."); diff --git a/Immutable_collections_java8_project/src/test/ImmutableArrayListTest.java b/Immutable_collections_java8_project/src/test/ImmutableArrayListTest.java index de65471..363a2fc 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableArrayListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableArrayListTest.java @@ -3,7 +3,7 @@ import org.junit.Before; -public class ImmutableArrayListTest extends ImmutableListTest { +public class ImmutableArrayListTest extends InductiveIterativeListTest { @Before public void setUp() { diff --git a/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java b/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java index dfb6d5b..2b6e1e2 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java @@ -17,7 +17,7 @@ import collections.implementations.ImmutableLinkedList; import collections.interfaces.ImmutableList; -public class ImmutableLinkedListTest extends ImmutableListTest { +public class ImmutableLinkedListTest extends InductiveIterativeListTest { @Before public void setUp() { diff --git a/Immutable_collections_java8_project/src/test/ImmutableReversedArrayListTest.java b/Immutable_collections_java8_project/src/test/ImmutableReversedArrayListTest.java index f9fe764..3338adb 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableReversedArrayListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableReversedArrayListTest.java @@ -3,7 +3,7 @@ import org.junit.Before; -public class ImmutableReversedArrayListTest extends ImmutableListTest { +public class ImmutableReversedArrayListTest extends InductiveIterativeListTest { @Before public void setUp() { diff --git a/Immutable_collections_java8_project/src/test/ImmutableListTest.java b/Immutable_collections_java8_project/src/test/InductiveIterativeListTest.java similarity index 91% rename from Immutable_collections_java8_project/src/test/ImmutableListTest.java rename to Immutable_collections_java8_project/src/test/InductiveIterativeListTest.java index afa3d98..6873a6b 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableListTest.java +++ b/Immutable_collections_java8_project/src/test/InductiveIterativeListTest.java @@ -18,51 +18,51 @@ import collections.implementations.ImmutableArrayList; import collections.implementations.ImmutableLinkedList; -import collections.interfaces.ImmutableList; +import collections.interfaces.InductiveIterativeList; interface ImmutableListFactory { - @SuppressWarnings("unchecked") public ImmutableList create(E... elems); - public ImmutableList create(); + @SuppressWarnings("unchecked") public InductiveIterativeList create(E... elems); + public InductiveIterativeList create(); } class ImmutableLinkedListFactory implements ImmutableListFactory { @SuppressWarnings({"unchecked"}) - public ImmutableList create(E... elems) { + public InductiveIterativeList create(E... elems) { return new ImmutableLinkedList(elems); } - public ImmutableList create() { + public InductiveIterativeList create() { return new ImmutableLinkedList(); } } class ImmutableArrayListFactory implements ImmutableListFactory { @SuppressWarnings({"unchecked"}) - public ImmutableList create(E... elems) { + public InductiveIterativeList create(E... elems) { return new ImmutableArrayList(elems); } - public ImmutableList create() { + public InductiveIterativeList create() { return new ImmutableArrayList(); } } class ReversedArrayListFactory implements ImmutableListFactory { @SuppressWarnings("unchecked") - public ImmutableList create(E... _elems) { + public InductiveIterativeList create(E... _elems) { List tmp = Arrays.asList(_elems); Collections.reverse(tmp); E[] elems = (E[]) tmp.toArray(); return new ImmutableArrayList(elems).reverse(); } - public ImmutableList create() { + public InductiveIterativeList create() { return new ImmutableArrayList().reverse(); } } -public abstract class ImmutableListTest { +public abstract class InductiveIterativeListTest { - protected ImmutableList list; - protected ImmutableList emptyList; + protected InductiveIterativeList list; + protected InductiveIterativeList emptyList; protected ImmutableListFactory factory; public void setUp(ImmutableListFactory factory) { @@ -108,10 +108,10 @@ public void SizeTest() { @Test public void SubListTest() { - ImmutableList empty = list.subList(0, 0); + InductiveIterativeList empty = list.subList(0, 0); assertTrue(empty.isEmpty()); - ImmutableList subList = list.subList(1, 3); + InductiveIterativeList subList = list.subList(1, 3); assertEquals(2, subList.size()); assertEquals(2, (int)subList.get(0)); assertEquals(3, (int)subList.get(1)); @@ -134,7 +134,7 @@ public void SubListExceptionTest3() { @Test public void MapTest() { - ImmutableList mappedList = list.map((Integer x) -> x * 2); + InductiveIterativeList mappedList = list.map((Integer x) -> x * 2); assertEquals(mappedList.size(), list.size()); assertEquals((int)mappedList.get(0), (int)2 * list.get(0)); assertEquals((int)mappedList.get(1), (int)2 * list.get(1)); @@ -143,7 +143,7 @@ public void MapTest() { @Test public void FilterTest() { - ImmutableList filteredList = list.filter((Integer x) -> x % 2 != 0); + InductiveIterativeList filteredList = list.filter((Integer x) -> x % 2 != 0); assertEquals(filteredList, new ImmutableLinkedList(1, 3)); filteredList = list.filter((Integer x) -> true); @@ -213,7 +213,7 @@ public void SubListIteratorTest() { // Test that iterators stop at the right last element for sublists // (since they all share their structures with a superlist) - ImmutableList subList = list.subList(1, list.size()-1); + InductiveIterativeList subList = list.subList(1, list.size()-1); assertEquals(1, subList.size()); int sizeWhenIterating = 0; @@ -378,7 +378,7 @@ public void hashCodeTest() { @Test public void toarrayTest(){ Integer[] array= { 1 ,2 ,3 }; - Integer[] array2 = new Integer[array.length]; + Integer[] array2 = new Integer[array.length]; array2=list.toArray(array); //TODO before : array2=list.toArray(array2) -> Check validity assertEquals(array2[0],array[0]); assertEquals(array2[1],array[1]); @@ -425,7 +425,7 @@ public void LastExceptionTest() { @Test public void TailTest() { - ImmutableList tail = list.tail(); + InductiveIterativeList tail = list.tail(); assertEquals(2, (int)tail.get(0)); assertEquals(3, (int)tail.get(1)); assertEquals(2, tail.size()); From f32bae0f9b85a07d855e24dd9b519f3ce8809d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Ferr=C3=A9?= Date: Sat, 7 Jun 2014 22:25:07 +0200 Subject: [PATCH 05/14] Add first POC of versionned linked list --- .../DoubleLinkedListProxy.java | 106 +++++++ .../collections/implementations/ListCell.java | 265 ++++++++++++++++++ .../VersionedDoubleLinkedList.java | 124 ++++++++ .../src/test/AllTests.java | 3 +- .../src/test/DoubleLinkedListProxyTest.java | 133 +++++++++ 5 files changed, 630 insertions(+), 1 deletion(-) create mode 100644 Immutable_collections_java8_project/src/collections/implementations/DoubleLinkedListProxy.java create mode 100644 Immutable_collections_java8_project/src/collections/implementations/ListCell.java create mode 100644 Immutable_collections_java8_project/src/collections/implementations/VersionedDoubleLinkedList.java create mode 100644 Immutable_collections_java8_project/src/test/DoubleLinkedListProxyTest.java diff --git a/Immutable_collections_java8_project/src/collections/implementations/DoubleLinkedListProxy.java b/Immutable_collections_java8_project/src/collections/implementations/DoubleLinkedListProxy.java new file mode 100644 index 0000000..98ce534 --- /dev/null +++ b/Immutable_collections_java8_project/src/collections/implementations/DoubleLinkedListProxy.java @@ -0,0 +1,106 @@ +package collections.implementations; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +public class DoubleLinkedListProxy /* implements List */ { + + /** The list we keep track of */ + private VersionedDoubleLinkedList versionedList; + + /** The first cell of the list */ + private ListCell cell; + + /** Version of the list this proxy should be wrapping */ + private int version; + + public DoubleLinkedListProxy() { + this(new VersionedDoubleLinkedList()); + } + + public DoubleLinkedListProxy(VersionedDoubleLinkedList versionedList) { + this.versionedList = versionedList; + this.cell = versionedList.getFirstCell(); + this.version = versionedList.getVersion(); + } + + public DoubleLinkedListProxy(VersionedDoubleLinkedList versionedList, + ListCell cell) { + this.versionedList = versionedList; + this.cell = cell; + this.version = versionedList.getVersion(); + } + + public DoubleLinkedListProxy nil() { // List + return new DoubleLinkedListProxy(); + } + + public boolean isEmpty() { + return versionedList.isEmpty(cell, version); + } + + public DoubleLinkedListProxy cons(E head) { // List + this.versionedList.addFirst(head, cell, version); + return new DoubleLinkedListProxy(versionedList, cell.getPrevious()); + } + + public DoubleLinkedListProxy tail() { // List + ListCell tailCell = versionedList.tail(cell, version); + return new DoubleLinkedListProxy(versionedList, tailCell); + } + + public E head() { + return this.versionedList.head(this.cell, this.version); + } + + public DoubleLinkedListProxy concat(DoubleLinkedListProxy that) { // List list + if (!(that instanceof DoubleLinkedListProxy)) + throw new UnsupportedOperationException(); + + DoubleLinkedListProxy thatList = (DoubleLinkedListProxy) that; + ListCell newCell = versionedList.concatenate(cell, + version, + thatList.versionedList, + thatList.cell, + thatList.version); + return new DoubleLinkedListProxy(versionedList, newCell); + } + + public DoubleLinkedListProxy reverse() { // List + this.versionedList.reverse(cell, version); + return new DoubleLinkedListProxy(versionedList, cell); + } + + public DoubleLinkedListProxy map(Function fctn) { // List + VersionedDoubleLinkedList newVersionedList = versionedList.map(cell, version, fctn); + return new DoubleLinkedListProxy(newVersionedList, newVersionedList.getFirstCell()); + } + + public DoubleLinkedListProxy endoMap(UnaryOperator op) { // List + versionedList.applyMap(cell, version, op); + return new DoubleLinkedListProxy(versionedList, cell); + } + + public String toString() { + return this.versionedList.toString(cell, version); + } + + public boolean equals(Object obj) { + if (!(obj instanceof DoubleLinkedListProxy)) { // List + return false; + } + if (obj instanceof DoubleLinkedListProxy) { + DoubleLinkedListProxy thatList = (DoubleLinkedListProxy) obj; + return versionedList.isEqual(cell, + version, + thatList.versionedList, + thatList.cell, + thatList.version); + } + // else { + // List thatList = (List) obj; // List list + // return versionedList.isEqual(cell, version, thatList); + // } + return false; // to suppr + } +} diff --git a/Immutable_collections_java8_project/src/collections/implementations/ListCell.java b/Immutable_collections_java8_project/src/collections/implementations/ListCell.java new file mode 100644 index 0000000..d47c961 --- /dev/null +++ b/Immutable_collections_java8_project/src/collections/implementations/ListCell.java @@ -0,0 +1,265 @@ +package collections.implementations; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +// import collections.interfaces.InductiveIterativeList; +// import collections.interfaces.IterativeList; +// import collections.interfaces.ImmutableList; + +public abstract class ListCell { + + /** The cell before this one in the linked list */ + protected ListCell previous; + + /** The cell after this one in the linked list */ + protected ListCell next; + + final public ListCell getPrevious() { + return previous; + } + + final public void setPrevious(ListCell l) { + this.previous = l; + } + + public ListCell getNext() { + return this.next; + } + + final public void setNext(ListCell l) { + this.next = l; + } + + final public boolean isFirst() { + return this.getPrevious().isEmpty(); + } + + abstract public boolean isEmpty(); + abstract public E getItem(); + abstract public void setItem(E item); + + abstract public void concat(ListCell cell); + abstract public void reverse(ListCell nilCell); + abstract public ListCell clone(); + abstract public ListCell map(Function mapper); + abstract public void applyMap(UnaryOperator mapper); + + abstract public boolean isEqual(ListCell cell); + // abstract public boolean isEqual(List list); + + static void linkCells(ListCell first, ListCell second) { + first.next = second; + second.previous = first; + } +} + +final class NilCell extends ListCell { + + public NilCell() { + this.previous = this; + this.next = this; + } + + public boolean isEmpty() { + return true; + } + + public E getItem() { + throw new UnsupportedOperationException(); + } + + public void setItem(E item) { + throw new UnsupportedOperationException(); + } + + public void concat(ListCell cell) { + throw new UnsupportedOperationException(); + } + + public void reverse(ListCell nilCell) { } + + public void applyMap(UnaryOperator mapper) { } + + public ListCell map(Function mapper) { + return new NilCell(); + } + + public boolean isEqual(ListCell cell) { + return cell.isEmpty(); + } + + // public boolean isEqual(List list) { + // return cell.isEmpty(); + // } + + public NilCell clone() { + return new NilCell(); + } + + public String toString() { + return "[]"; + } +} + +class ConsCell extends ListCell { + + /** The element of this cell */ + private E item; + + public ConsCell(E head, ListCell tail) { + setItem(head); + this.next = tail; + this.previous = tail.previous; + tail.previous = this; + this.previous.next = this; + } + + private ConsCell(E item) { + this.item = item; + } + + public boolean isEmpty() { + return false; + } + + public E getItem() { + return item; + } + + public void setItem(E item) { + this.item = item; + } + + // TODO: do not copy & ++version + public void concat(ListCell _cell) { + ListCell cell = _cell.clone(); + ListCell lastButOne = this.previous.previous; + this.previous = cell.previous; + linkCells(lastButOne, cell); + } + + // ++version + public void reverse(ListCell nilCell) { + ListCell rightCell = nilCell.previous; + ListCell leftCell = this; + + while (leftCell != rightCell) { + E rightItem = rightCell.getItem(); + rightCell.setItem(leftCell.getItem()); + leftCell.setItem(rightItem); + + if(leftCell.next == rightCell) { + break; + } + + leftCell = leftCell.next; + rightCell = rightCell.previous; + } + } + + public ListCell clone() { + ListCell cell = this; + ListCell result = new ConsCell<>(cell.getItem()); + ListCell newCell = result; + cell = cell.getNext(); + + while (!cell.isEmpty()) { + ListCell newNextCell = new ConsCell<>(cell.getItem()); + linkCells(newCell, newNextCell); + + newCell = newNextCell; + cell = cell.getNext(); + } + + ListCell newNilCell = cell.clone(); + linkCells(newNilCell, result); + linkCells(newCell, newNilCell); + + return result; + } + + public ListCell map(Function mapper) { + ListCell cell = this; + ListCell result = new ConsCell<>(mapper.apply(cell.getItem())); + ListCell newCell = result; + cell = cell.getNext(); + + while (!cell.isEmpty()) { + ListCell newNextCell = new ConsCell<>(mapper.apply(cell.getItem())); + linkCells(newCell, newNextCell); + newCell = newNextCell; + cell = cell.getNext(); + } + + ListCell newNilCell = cell.map(mapper); + linkCells(newNilCell, result); + linkCells(newCell, newNilCell); + + return result; + } + + // ++version + public void applyMap(UnaryOperator mapper) { + ListCell cell = this; + cell.setItem(mapper.apply(cell.getItem())); + cell = cell.getNext(); + while (!cell.isEmpty()) { + cell.setItem(mapper.apply(cell.getItem())); + cell = cell.getNext(); + } + } + + public boolean isEqual(ListCell cell) { + if(cell.isEmpty()) + return false; + if (!this.getItem().equals(cell.getItem())) + return false; + + ListCell thisCell = this.getNext(); + cell = cell.getNext(); + while (!thisCell.isEmpty()) { + + if (cell.isEmpty()) + return false; + if(!thisCell.getItem().equals(cell.getItem())) + return false; + + thisCell = thisCell.getNext(); + cell = cell.getNext(); + } + return thisCell.isEqual(cell); + } + + // public boolean isEqual(List list) { + // if (list.isEmpty()) + // return false; + // if (!this.getItem().equals(list.head())) + // return false; + + // ListCell thisCell = this.getNext(); + // list = list.tail(); + // while (!thisCell.isEmpty()){ + + // if(list.isEmpty()) + // return false; + // if(!thisCell.getItem().equals(list.head())) + // return false; + + // thisCell = thisCell.getNext(); + // list = list.tail(); + // } + // return thisCell.isEqual(list); + // } + + public String toString(){ + String result = "[" + this.getItem(); + ListCell thisCell = this.getNext(); + String sep = ", "; + while (!thisCell.isEmpty()) { + result = result + sep + thisCell.getItem(); + thisCell = thisCell.getNext(); + } + return result + "]"; + } +} diff --git a/Immutable_collections_java8_project/src/collections/implementations/VersionedDoubleLinkedList.java b/Immutable_collections_java8_project/src/collections/implementations/VersionedDoubleLinkedList.java new file mode 100644 index 0000000..7859a02 --- /dev/null +++ b/Immutable_collections_java8_project/src/collections/implementations/VersionedDoubleLinkedList.java @@ -0,0 +1,124 @@ +package collections.implementations; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +// TODO: double pointer +public final class VersionedDoubleLinkedList { + + private ListCell firstCell; + private int version; + + public VersionedDoubleLinkedList() { + this(new NilCell(), 0); + } + + public VersionedDoubleLinkedList(ListCell newFirstCell, int version) { + this.version = version; + this.firstCell = newFirstCell; + } + + public ListCell getFirstCell(){ + return this.firstCell; + } + + public int getVersion() { + return this.version; + } + + private void checkVersion(int clientVersion) { + if (clientVersion == this.version) + return; + throw new UnsupportedOperationException("Version is outdated. Found: " + + clientVersion + + " - Expected: " + + this.version); + } + + public void addFirst(E head, ListCell cell, int clientVersion) { + this.checkVersion(clientVersion); + if (cell.isFirst()) { + this.firstCell = new ConsCell(head, cell); + } else { + this.version++; + cell.getPrevious().setItem(head); + } + } + + public ListCell tail(ListCell thisCell, int thisVersion) { + this.checkVersion(thisVersion); + return thisCell.getNext(); + } + + public E head(ListCell thisCell, int thisVersion) { + this.checkVersion(thisVersion); + return thisCell.getItem(); + } + + public ListCell concatenate(ListCell thisCell, + int thisVersion, + VersionedDoubleLinkedList other, + ListCell otherCell, + int otherVersion) { + this.checkVersion(thisVersion); + other.checkVersion(otherVersion); + + if (otherCell.isEmpty()) + return thisCell; + + if (thisCell.isEmpty()) { + this.version++; + this.firstCell = otherCell.clone(); // TODO: do not copy + return this.firstCell; + } else { + this.version++; + this.firstCell.concat(otherCell); + return thisCell; + } + } + + public void reverse(ListCell thisCell, int thisVersion) { + this.checkVersion(thisVersion); + this.version++; + thisCell.reverse(firstCell.previous); + } + + public boolean isEmpty(ListCell cell, int thisVersion) { + this.checkVersion(thisVersion); + return cell.isEmpty(); + } + + public VersionedDoubleLinkedList map(ListCell thisCell, int thisVersion, Function mapper) { + this.checkVersion(thisVersion); + ListCell newCell = thisCell.map(mapper); + return new VersionedDoubleLinkedList(newCell, 0); + } + + public void applyMap(ListCell thisCell, int thisVersion, UnaryOperator op) { + this.checkVersion(thisVersion); + this.version++; + thisCell.applyMap(op); + } + + public boolean isEqual(ListCell thisCell, + int thisVersion, + VersionedDoubleLinkedList that, + ListCell otherCell, + int otherVersion) { + + this.checkVersion(thisVersion); + that.checkVersion(otherVersion); + + return thisCell.isEqual(otherCell); + } + + // public boolean isEqual(ListCell thisCell, int thisVersion, List thatList){ + // this.checkVersion(thisVersion); + // return thisCell.isEqual(thatList); + // } + + public String toString(ListCell thisCell, int thisVersion) { + this.checkVersion(thisVersion); + return thisCell.toString(); + } +} diff --git a/Immutable_collections_java8_project/src/test/AllTests.java b/Immutable_collections_java8_project/src/test/AllTests.java index 42ac8f1..dc76549 100644 --- a/Immutable_collections_java8_project/src/test/AllTests.java +++ b/Immutable_collections_java8_project/src/test/AllTests.java @@ -8,7 +8,8 @@ @SuiteClasses({ ImmutableArrayListTest.class, ImmutableLinkedListTest.class, - ImmutableReversedArrayListTest.class + ImmutableReversedArrayListTest.class, + DoubleLinkedListProxyTest.class }) public class AllTests { diff --git a/Immutable_collections_java8_project/src/test/DoubleLinkedListProxyTest.java b/Immutable_collections_java8_project/src/test/DoubleLinkedListProxyTest.java new file mode 100644 index 0000000..eca96e9 --- /dev/null +++ b/Immutable_collections_java8_project/src/test/DoubleLinkedListProxyTest.java @@ -0,0 +1,133 @@ +package test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collections; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.stream.Stream; + +import org.junit.Test; + +import collections.implementations.*; + +public class DoubleLinkedListProxyTest { + + DoubleLinkedListProxy list; + DoubleLinkedListProxy nil; + + @Before + public void setUp() { + list = new DoubleLinkedListProxy(); + nil = list.nil(); + } + + @Test + public void testNil() { + assertTrue(nil.isEmpty()); + } + + @Test + public void testIsEmpty() { + assertTrue(list.isEmpty()); + assertFalse(list.cons(1).isEmpty()); + } + + // @Test(expected=UnsupportedOperationException.class) + public void testTailException() { // TODO: should throw an exception + // nil.tail(); + assertEquals(nil, nil.tail()); + } + + @Test + public void testTail() { + list = list.cons(1); + list = list.cons(2); + assertEquals(nil.cons(1), list.tail()); + } + + @Test(expected=UnsupportedOperationException.class) + public void testHeadException() { + list.head(); + } + + @Test + public void testHead() { + list = list.cons(1).cons(2); + assertEquals(2, (int)list.head()); + } + + @Test + public void testCons() { + list = list.cons(3); + list = list.cons(2); + list = list.cons(1); + + assertEquals(1, (int)list.head()); list = list.tail(); + assertEquals(2, (int)list.head()); list = list.tail(); + assertEquals(3, (int)list.head()); + } + + @Test + public void testConcat() { + assertEquals(nil, list.concat(list)); + + DoubleLinkedListProxy expected = nil.cons(2).cons(1); + DoubleLinkedListProxy one = new DoubleLinkedListProxy().cons(1); + DoubleLinkedListProxy two = new DoubleLinkedListProxy().cons(2); + assertEquals(expected, one.concat(two)); + } + + @Test + public void testReverse() { + assertEquals(nil, list.reverse()); + + DoubleLinkedListProxy expected = new DoubleLinkedListProxy(); + expected = expected.cons(3).cons(2).cons(1); + + list = nil.cons(1).cons(2).cons(3); + assertEquals(expected, list.reverse()); + } + + @Test + public void testMap() { + list = list.cons(1).cons(2).cons(3); + + DoubleLinkedListProxy expected = new DoubleLinkedListProxy(); + expected = expected.cons(2).cons(4).cons(6); + + assertEquals(expected, list.map((Integer x) -> x * 2)); + } + + @Test + public void testEndoMap() { + list = list.cons(1).cons(2).cons(3); + + DoubleLinkedListProxy expected = new DoubleLinkedListProxy(); + expected = expected.cons(2).cons(4).cons(6); + + assertEquals(expected, list.endoMap((Integer x) -> x * 2)); + } + + @Test + public void testEquals() { + assertEquals(nil, list); + + list = list.cons(3).cons(2).cons(1); + DoubleLinkedListProxy expected = new DoubleLinkedListProxy(); + expected = expected.cons(3).cons(2); + assertFalse(expected.equals(list)); + + expected = expected.cons(1); + assertEquals(expected, list); + } +} From b6009cff6d3fa9e3315d7e90825a2def3d967f86 Mon Sep 17 00:00:00 2001 From: Theophile Morin Date: Wed, 11 Jun 2014 18:04:28 +0200 Subject: [PATCH 06/14] Benchmarks corrected. All tests pass with succes. --- .gitignore | 1 + .../src/main/Benchmarks.java | 20 +++++++++---------- .../src/main/Main.java | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index fce5816..b340036 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.class +*.orig # Directories # /build/ diff --git a/Immutable_collections_java8_project/src/main/Benchmarks.java b/Immutable_collections_java8_project/src/main/Benchmarks.java index 8ffbf25..6a84780 100644 --- a/Immutable_collections_java8_project/src/main/Benchmarks.java +++ b/Immutable_collections_java8_project/src/main/Benchmarks.java @@ -7,15 +7,15 @@ import collections.implementations.ImmutableArrayList; import collections.implementations.ImmutableLinkedList; -import collections.interfaces.ImmutableList; +import collections.interfaces.InductiveIterativeList; public class Benchmarks { - ImmutableList ill; /** ImmutableLinkedList implementation */ - ImmutableList ial; /** ImmutableArrayList implementation */ + InductiveIterativeList ill; /** ImmutableLinkedList implementation */ + InductiveIterativeList ial; /** ImmutableArrayList implementation */ List ll; /** LinkedList implementation */ List al; /** ArrayList implementation */ - ImmutableList hial; /** Half ImmutableLinkedList implementation */ + InductiveIterativeList hial; /** Half ImmutableLinkedList implementation */ List dummy; /** List implementation needed to concat */ public Benchmarks(int size) @@ -82,7 +82,7 @@ public void runHalfImmuLinkedListBench(int warmup, int maxIterations) - private void execAll(ImmutableList list, int warmup, int maxIterations) + private void execAll(InductiveIterativeList list, int warmup, int maxIterations) { long execTime = 0; @@ -121,7 +121,7 @@ private void execAll(List list, int warmup, int maxIterations) - private long execGet(ImmutableList list, int warmup, int maxIterations) + private long execGet(InductiveIterativeList list, int warmup, int maxIterations) { long beg = 0; long end = 0; @@ -165,7 +165,7 @@ private long execGet(List list, int warmup, int maxIterations) return (execTime/warmup); } - private long execSize(ImmutableList list, int warmup, int maxIterations) + private long execSize(InductiveIterativeList list, int warmup, int maxIterations) { long beg = 0; long end = 0; @@ -207,7 +207,7 @@ private long execSize(List list, int warmup, int maxIterations) return (execTime/warmup); } - private long execIndexOf(ImmutableList list, int warmup, int maxIterations) + private long execIndexOf(InductiveIterativeList list, int warmup, int maxIterations) { long beg = 0; long end = 0; @@ -252,12 +252,12 @@ private long execIndexOf(List list, int warmup, int maxIterations) } - private long execConcat(ImmutableList list, int warmup, int maxIterations) + private long execConcat(InductiveIterativeList list, int warmup, int maxIterations) { long beg = 0; long end = 0; @SuppressWarnings("unused") - ImmutableList out; + InductiveIterativeList out; long execTime = 0; for(int i=0; i < warmup; ++i) diff --git a/Immutable_collections_java8_project/src/main/Main.java b/Immutable_collections_java8_project/src/main/Main.java index bc10585..4e8c432 100644 --- a/Immutable_collections_java8_project/src/main/Main.java +++ b/Immutable_collections_java8_project/src/main/Main.java @@ -5,7 +5,7 @@ public class Main { public static void main(String[] args) { System.out.println("Main."); Benchmarks bench = new Benchmarks(100); - bench.run(10, 10000); + bench.run(10, 1000); } } From 7b5354aad182f870ea9aba0893f31196ab0d3903 Mon Sep 17 00:00:00 2001 From: Theophile Morin Date: Wed, 11 Jun 2014 22:38:41 +0200 Subject: [PATCH 07/14] Interfaces name refactoring. Implementation of abstract classes. --- .../ImmutableAbstractInductiveList.java | 49 +++ .../ImmutableAbstractIterativeList.java | 29 ++ .../interfaces/ImmutableCoreList.java | 366 ++++++++++++++++++ 3 files changed, 444 insertions(+) create mode 100644 Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractInductiveList.java create mode 100644 Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractIterativeList.java create mode 100644 Immutable_collections_java8_project/src/collections/interfaces/ImmutableCoreList.java diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractInductiveList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractInductiveList.java new file mode 100644 index 0000000..0de4cb0 --- /dev/null +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractInductiveList.java @@ -0,0 +1,49 @@ +package collections.implementations; + +import java.util.NoSuchElementException; + +import collections.interfaces.ImmutableCoreList; +import collections.interfaces.InductiveList; + +public abstract class ImmutableAbstractInductiveList implements InductiveList { + + @Override + public boolean isEmpty() { + return false; //TODO find why this method is not implemented in concrete class (ImmutableLinkedList). + } + + @Override + public ImmutableCoreList clone() { //TODO check static returned type. + return ImmutableCoreList.clone(this); //TODO check call + } + + @Override + public boolean equals(Object o) { + return ImmutableCoreList.equals(this, o);//TODO check call to first background interface while InductiveList + } + + @Override + public int hashCode() { + return ImmutableCoreList.hashCode(this); //TODO check call to first background interface while InductiveList + } + + @Override + public InductiveList cons(E elem) { + return null; // new ImmutableLinkedList(new Node(elem, head()), last(), size() + 1); //TODO add size in Core ? + } + + @Override + public E head() throws NoSuchElementException { //TODO implementation class call an accessor method, check it. + return null; + } + + @Override + public InductiveList tail() throws UnsupportedOperationException { //TODO ERROR : check why tail is not implemented in the implementation class... + return null; + } + + @Override + public E last() throws NoSuchElementException { //TODO implementation class call an accessor method, check it. + return null; + } +} diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractIterativeList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractIterativeList.java new file mode 100644 index 0000000..89736c9 --- /dev/null +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractIterativeList.java @@ -0,0 +1,29 @@ +package collections.implementations; + +import collections.interfaces.ImmutableCoreList; +import collections.interfaces.IterativeList; + +public abstract class ImmutableAbstractIterativeList implements IterativeList +{ + + @Override + public E get(int index) throws IndexOutOfBoundsException { + return null; //TODO refers to the implementation class + } + + @Override + public boolean equals(Object o) { + return IterativeList.equals(this, o); //TODO check "this" validity (abstract class) + } + + @Override + public ImmutableCoreList clone() { //TODO check static returned type + return ImmutableCoreList.clone(this); //TODO check "this" validity (abstract class) + } + + @Override + public int hashCode() { + return ImmutableCoreList.hashCode(this); //TODO check "this" validity (abstract class) + } + +} diff --git a/Immutable_collections_java8_project/src/collections/interfaces/ImmutableCoreList.java b/Immutable_collections_java8_project/src/collections/interfaces/ImmutableCoreList.java new file mode 100644 index 0000000..f6b660b --- /dev/null +++ b/Immutable_collections_java8_project/src/collections/interfaces/ImmutableCoreList.java @@ -0,0 +1,366 @@ +package collections.interfaces; + +// http://www.scala-lang.org/api/2.11.0/index.html#scala.collection.immutable.List +// http://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true +// http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableList.html + +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.ArrayList; +import java.util.Optional; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public interface ImmutableCoreList extends Iterable, +Cloneable { + + public ImmutableCoreList create(E[] elems); + public ImmutableCoreList create(Collection elems); + + /** + * Returns true if this list contains no elements. + * + * @returns true if this list contains no elements + */ + boolean isEmpty(); + + /** + * Sorts this list using the supplied Comparator to compare elements. + * @param comparator + * @return the list + */ + default ImmutableCoreList sort(Comparator comparator) { + E[] a = (E[]) toArray(); + Arrays.sort(a, comparator); + return create(a); + } + + /** + * Returns whether given predicate is satisfied by at least one element + * of the list. + * + * @param predicate The predicate to be tested on elements of the list. + * @returns true if predicate is satisfied by at least one element of + * the list. + */ + default boolean any(Predicate predicate) { + for (E elem : this) + if (predicate.test(elem)) + return true; + return false; + } + + /** + * Returns whether given predicate is satisfied by all elements of the + * list. + * + * @param predicate The predicate to be tested on elements of the list. + * @returns true if predicate is satified by all elements of the list. + */ + default boolean all(Predicate predicate) { + for (E elem : this) + if (!predicate.test(elem)) + return false; + return true; + } + + /** + * Returns the first index where the element is located in the list, or -1. + * + * @param o the element to look for + * @return its position, or -1 if not found + */ + default int indexOf(E elem) { + int i = 0; + for (E other : this) + if (equals(elem, other)) + return i; + else + ++i; + return -1; + } + + /** + * Compare two objects according to Collection semantics. + * + * @param o1 the first object + * @param o2 the second object + * @return o1 == null ? o2 == null : o1.equals(o2) + */ + static boolean equals(Object o1, Object o2) { + return o1 == null ? o2 == null : o1.equals(o2); + } + + /** + * Returns true if this list contains the specified element. More formally, + * returns true if and only if this list contains at least one element e + * such that (o==null ? e==null : o.equals(e)). + * + * @param elem the element to look for + * @return true if it is found + */ + default boolean contains(E elem) { + return any((E other) -> equals(elem, other)); + } + + /** + * Returns true if this list contains all of the elements of the + * specified collection. + * + * @param elems the elements to look for + * @return true if this list contains all of the elements of the + * specified collection + */ + default boolean containsAll(Collection elems) { + return containsAll(create(elems)); + } + + /** + * Returns true if this list contains all of the elements of the + * specified list. + * + * @param elems the elements to look for + * @return true if this list contains all of the elements of the + * specified list + */ + default boolean containsAll(ImmutableCoreList elems) { + return elems.all((E elem) -> contains(elem)); + } + + /** + * Returns true if this list contains all of the given elements + * + * @param elems the elements to look for + * @return true if this list contains all of the given elements + */ + @SuppressWarnings({"unchecked"}) + default boolean containsAll(E... elems) { + return containsAll(create(elems)); + } + + /** + * Returns a new list consisting of the results of applying the given + * function to the elements of this list. + * + * @param mapper a function to apply to each element + * @returns the new list + */ + default ImmutableCoreList map(Function mapper) { + List elems = new ArrayList(); + for (E elem : this) { + elems.add(mapper.apply(elem)); + } + return create(elems); + } + + /** + * Returns a list consisting of the elements of this list that match the + * given predicate. + * + * @param predicate The predicate to be tested on elements of the list. + * @return a list consisting of the elements of this list that match the + * given predicate. + */ + default ImmutableCoreList filter(Predicate predicate) { + ArrayList list = new ArrayList(); + for (E elem : this) + if (predicate.test(elem)) + list.add(elem); + return create(list); + } + + /** + * Performs a reduction on the elements of this list, using an associative + * accumulation function, and returns an Optional describing the reduced + * value, if any. + * + * @param accumulator An associative function for combining two values + * @return an Optional describing the result of the reduction + * @throws NullPointerException - if the result of the reduction is null + */ + default Optional reduce(BinaryOperator accumulator) { + Iterator it = iterator(); + if (!it.hasNext()) + return Optional.empty(); + + E result = it.next(); + while (it.hasNext()) + result = accumulator.apply(result, it.next()); + return Optional.of(result); + } + + default Spliterator spliterator() { + return Spliterators.spliteratorUnknownSize(iterator(), + Spliterator.IMMUTABLE | + Spliterator.ORDERED); + } + + /** + * Returns a sequential Stream with this collection as its source. + * + * @return a sequential Stream over the elements in this collection + */ + default Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + /** + * Returns a parallel Stream with this collection as its source. + * + * @return a parallel Stream over the elements in this collection + */ + default Stream parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + /** + * Returns an array containing all of the elements in this list in + * proper sequence (from first to last element). + * + * The returned array will be "safe" in that no references to it are + * maintained by this list. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * This method acts as bridge between array-based and collection-based APIs. + * + * @return an array containing all of the elements in this list in + * proper sequence + */ + @SuppressWarnings("unchecked") + default E[] toArray() { //TODO unused E elem + int size = 0; + for ( E elem : this) + ++size; + return toArray((E[]) new Object[size]); + } + + /** + * Returns an array containing all of the elements in this list in + * proper sequence (from first to last element); the runtime type of the + * returned array is that of the specified array. If the list fits in + * the specified array, it is returned therein. Otherwise, a new array + * is allocated with the runtime type of the specified array and the + * size of this list. + * + * If the list fits in the specified array with room to spare (i.e., the + * array has more elements than the list), the element in the array + * immediately following the end of the list is set to null. (This is + * useful in determining the length of the list only if the caller knows + * that the list does not contain any null elements.) + * + * Like the toArray() method, this method acts as bridge between array- + * based and collection-based APIs. Further, this method allows precise + * control over the runtime type of the output array, and may, under + * certain circumstances, be used to save allocation costs. + * + * Suppose x is a list known to contain only strings. The following code + * can be used to dump the list into a newly allocated array of String: + * String[] y = x.toArray(new String[0]); + * + * Note that toArray(new Object[0]) is identical in function to toArray(). + * + * @param a -the array into which the elements of the list are to be + * stored, if it is big enough; otherwise, a new array of the same + * runtime type is allocated for this purpose. + * @return an array containing the elements of the list + */ + + default E[] toArray(E[] a) { + int i = 0; + for (E elem : this) { + a[i] = elem; + ++i; + } + return a; + } + + /** + * Returns a list containing all of the elements in this list in proper + * sequence. + * + * @return a list containing all of the elements in this list in proper + * sequence + */ + default List asList() { + List myList = new ArrayList(); + for (E e : this){ + myList.add(e); + } + return myList; + } + + public ImmutableCoreList clone(); + + // To be used for the clone() method in concrete classes (since Object + // methods cannot be overriden with the default keyword) + static ImmutableCoreList clone(ImmutableCoreList list) { + return list.create(list.asList()); + } + + /** + * Compares the specified object with this list for equality. Returns true + * if and only if the specified object is also a list, both lists have the + * same size, and all corresponding pairs of elements in the two lists are + * equal. (Two elements e1 and e2 are equal if + * (e1==null ? e2==null : e1.equals(e2)).) In other words, two + * lists are defined to be equal if they contain the same elements in the + * same order. This definition ensures that the equals method works properly + * across different implementations of the ImmutableList interface. + * + * @param o the object to be compared for equality with this list + * @return if the specified object is equal to this list + */ + boolean equals(Object o); + + // To be used for the equals() method in concrete classes (since Object + // methods cannot be overriden with the default keyword) + static boolean equals(ImmutableCoreList list, Object o) { + if (! (o instanceof ImmutableCoreList)) + return false; + + @SuppressWarnings("rawtypes") + ImmutableCoreList other = (ImmutableCoreList) o; + + Iterator it1 = list.iterator(); + @SuppressWarnings("rawtypes") Iterator it2 = other.iterator(); + + while (it1.hasNext() && it2.hasNext()) { + if (!equals(it1.next(), it2.next())) + return false; + } + if (it1.hasNext() || it2.hasNext()) + return false; + + return true; + } + + /** + * Hash an object. + * + * @param o the object to hash + * @return o1 == null ? 0 : o1.hashCode() + */ + static int hashCode(Object o) { + return o == null ? 0 : o.hashCode(); + } + + public int hashCode(); + + // To be used for the hashCode() method in concrete classes (since Object + // methods cannot be overriden with the default keyword) + static int hashCode(ImmutableCoreList list) { + int hashCode = 1; + Iterator itr = list.iterator(); + while (itr.hasNext()) + hashCode = 31 * hashCode + hashCode(itr.next()); + return hashCode; + } +} From d2bf923239db42eb1439aea9faeee5ce9b545a76 Mon Sep 17 00:00:00 2001 From: Theophile Morin Date: Wed, 11 Jun 2014 22:38:53 +0200 Subject: [PATCH 08/14] Interfaces name refactoring. Implementation of abstract classes. --- .../implementations/ImmutableArrayList.java | 16 +- .../implementations/ImmutableLinkedList.java | 13 +- .../collections/interfaces/ImmutableList.java | 460 +++++++----------- .../interfaces/InductiveIterativeList.java | 235 --------- .../collections/interfaces/InductiveList.java | 11 +- .../collections/interfaces/IterativeList.java | 40 +- .../src/main/Benchmarks.java | 58 +-- .../src/test/DoubleLinkedListProxyTest.java | 15 +- .../src/test/ImmutableLinkedListTest.java | 15 - .../src/test/InductiveIterativeListTest.java | 38 +- 10 files changed, 255 insertions(+), 646 deletions(-) delete mode 100644 Immutable_collections_java8_project/src/collections/interfaces/InductiveIterativeList.java diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java index c9bd39a..e1f005b 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java @@ -4,11 +4,11 @@ import java.util.Iterator; import java.util.NoSuchElementException; -import collections.interfaces.InductiveIterativeList; -import collections.interfaces.IterativeList; +import collections.interfaces.ImmutableCoreList; import collections.interfaces.ImmutableList; +import collections.interfaces.IterativeList; -public class ImmutableArrayList implements InductiveIterativeList +public class ImmutableArrayList implements ImmutableList { private final E[] _array; @@ -125,10 +125,10 @@ public int size() { return _length; } - public E get(int index) { + public E get(int index) { //TODO create an accessor for the _array and put the code into the absract class. if (index < 0 || index >= size()) throw new IndexOutOfBoundsException(); - if(index >=0 && index < _length) + if(index >=0 && index < size()) return _array[index]; else return null; @@ -203,11 +203,11 @@ public ImmutableArrayList cons(E elem) { public int hashCode() { - return ImmutableList.hashCode(this); + return ImmutableCoreList.hashCode(this); } - public InductiveIterativeList clone() { - return InductiveIterativeList.clone(this); + public ImmutableList clone() { + return ImmutableList.clone(this); } public boolean equals(Object o) { diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java index 10d29a9..2013b09 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java @@ -4,9 +4,9 @@ import java.util.Iterator; import java.util.NoSuchElementException; -import collections.interfaces.InductiveIterativeList; -import collections.interfaces.IterativeList; +import collections.interfaces.ImmutableCoreList; import collections.interfaces.ImmutableList; +import collections.interfaces.IterativeList; class Node { @@ -51,7 +51,7 @@ public boolean hasNext() { } } -public class ImmutableLinkedList implements InductiveIterativeList { +public class ImmutableLinkedList implements ImmutableList { /** The first node element of the list. */ private final Node head; @@ -183,7 +183,6 @@ public E last() throws NoSuchElementException { return lastNode().getElement(); } - @SuppressWarnings("unchecked") public ImmutableLinkedList subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException, IllegalArgumentException { @@ -291,11 +290,11 @@ public Iterator iterator() { } public int hashCode() { - return ImmutableList.hashCode(this); + return ImmutableCoreList.hashCode(this); //TODO check call to first background interface while ImmutableList } - public InductiveIterativeList clone() { - return InductiveIterativeList.clone(this); + public ImmutableList clone() { + return ImmutableList.clone(this); } public boolean equals(Object o) { diff --git a/Immutable_collections_java8_project/src/collections/interfaces/ImmutableList.java b/Immutable_collections_java8_project/src/collections/interfaces/ImmutableList.java index 03d9e94..2b6075d 100644 --- a/Immutable_collections_java8_project/src/collections/interfaces/ImmutableList.java +++ b/Immutable_collections_java8_project/src/collections/interfaces/ImmutableList.java @@ -1,367 +1,235 @@ package collections.interfaces; -// http://www.scala-lang.org/api/2.11.0/index.html#scala.collection.immutable.List -// http://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true -// http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableList.html - -import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; -import java.util.Optional; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Predicate; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; +import java.util.NoSuchElementException; -public interface ImmutableList extends Iterable, - Cloneable { +public interface ImmutableList extends InductiveList, IterativeList { public ImmutableList create(E[] elems); - public ImmutableList create(Collection elems); /** - * Returns true if this list contains no elements. + * Returns a portion of this list. * - * @returns true if this list contains no elements - */ - boolean isEmpty(); - - /** - * Sorts this list using the supplied Comparator to compare elements. - * @param comparator - * @return the list + * @param fromIndex low endpoint (inclusive) of the subList + * @param toIndex high endpoint (exclusive) of the subList + * @returns a portion of this list + * @throws IndexOutOfBoundsException if an endpoint index value is out + * of range (fromIndex < 0 || toIndex > size) + * @throws IllegalArgumentException if the endpoint indices are out of + * order (fromIndex > toIndex) */ - default ImmutableList sort(Comparator comparator) { - @SuppressWarnings({"unchecked"}) - E[] a = (E[]) toArray(); - Arrays.sort(a, comparator); - return create(a); - } + ImmutableList subList(int fromIndex, int toIndex) throws + IndexOutOfBoundsException, + IllegalArgumentException; /** - * Returns whether given predicate is satisfied by at least one element - * of the list. + * Returns a new list with the elements of this list in reverse order. * - * @param predicate The predicate to be tested on elements of the list. - * @returns true if predicate is satisfied by at least one element of - * the list. + * @return a new list with the elements of this list in reverse order. */ - default boolean any(Predicate predicate) { - for (E elem : this) - if (predicate.test(elem)) - return true; - return false; + default ImmutableList reverse() { + if (isEmpty()) + return this; + else + return tail().reverse().concat(head()); } /** - * Returns whether given predicate is satisfied by all elements of the - * list. + * Returns a new list containing the elements from this list followed by + * the elements from the given list. * - * @param predicate The predicate to be tested on elements of the list. - * @returns true if predicate is satified by all elements of the list. + * @param elems the list to be concatened with + * @returns a new list containing the elements from this list followed + * by the elements from the given list */ - default boolean all(Predicate predicate) { - for (E elem : this) - if (!predicate.test(elem)) - return false; - return true; + default ImmutableList concat(Collection elems) { + ImmutableList list = this; + for (E elem : elems){ + list = list.concat(elem); + } + return list; } /** - * Returns the first index where the element is located in the list, or -1. - * - * @param o the element to look for - * @return its position, or -1 if not found - */ - default int indexOf(E elem) { - int i = 0; - for (E other : this) - if (equals(elem, other)) - return i; - else - ++i; - return -1; - } - - /** - * Compare two objects according to Collection semantics. - * - * @param o1 the first object - * @param o2 the second object - * @return o1 == null ? o2 == null : o1.equals(o2) - */ - static boolean equals(Object o1, Object o2) { - return o1 == null ? o2 == null : o1.equals(o2); - } - - /** - * Returns true if this list contains the specified element. More formally, - * returns true if and only if this list contains at least one element e - * such that (o==null ? e==null : o.equals(e)). - * - * @param elem the element to look for - * @return true if it is found - */ - default boolean contains(E elem) { - return any((E other) -> equals(elem, other)); - } - - /** - * Returns true if this list contains all of the elements of the - * specified collection. + * Returns a new list containing the elements from this list followed by + * the elements from the given list. * - * @param elems the elements to look for - * @return true if this list contains all of the elements of the - * specified collection + * @param elems the list to be concatened with + * @returns a new list containing the elements from this list followed + * by the elements from the given list */ - default boolean containsAll(Collection elems) { - return containsAll(create(elems)); - } - - /** - * Returns true if this list contains all of the elements of the - * specified list. - * - * @param elems the elements to look for - * @return true if this list contains all of the elements of the - * specified list - */ - default boolean containsAll(ImmutableList elems) { - return elems.all((E elem) -> contains(elem)); - } + default ImmutableList concat(ImmutableList elems) { + ImmutableList list = this; + for (E elem : elems){ + list = list.concat(elem); + } + return list; + } /** - * Returns true if this list contains all of the given elements + * Returns a new list containing the elements from this list followed by + * the elements from the given list. * - * @param elems the elements to look for - * @return true if this list contains all of the given elements + * @param elems the list to be concatened with + * @returns a new list containing the elements from this list followed + * by the elements from the given list */ @SuppressWarnings({"unchecked"}) - default boolean containsAll(E... elems) { - return containsAll(create(elems)); + default ImmutableList concat(E... elems) { + ImmutableList list = this; + for (int i = 0 ; i ImmutableList map(Function mapper) { - List elems = new ArrayList(); - for (E elem : this) { - elems.add(mapper.apply(elem)); + default ImmutableList concat(E elem) { + @SuppressWarnings("unchecked") + E[] elems = (E[]) new Object[size() + 1]; + int i = 0; + for (E e : this) { + elems[i] = e; + ++i; } + elems[size()] = elem; return create(elems); } /** - * Returns a list consisting of the elements of this list that match the - * given predicate. + * Returns a new list without all the elements of the specified + * elements from this list. * - * @param predicate The predicate to be tested on elements of the list. - * @return a list consisting of the elements of this list that match the - * given predicate. + * @param elems - elements to be removed from this list, if present + * @return a new list without all the elements of the specified + * elements from this list */ - default ImmutableList filter(Predicate predicate) { - ArrayList list = new ArrayList(); - for (E elem : this) - if (predicate.test(elem)) - list.add(elem); - return create(list); - } - - /** - * Performs a reduction on the elements of this list, using an associative - * accumulation function, and returns an Optional describing the reduced - * value, if any. - * - * @param accumulator An associative function for combining two values - * @return an Optional describing the result of the reduction - * @throws NullPointerException - if the result of the reduction is null - */ - default Optional reduce(BinaryOperator accumulator) { - Iterator it = iterator(); - if (!it.hasNext()) - return Optional.empty(); - - E result = it.next(); - while (it.hasNext()) - result = accumulator.apply(result, it.next()); - return Optional.of(result); - } - - default Spliterator spliterator() { - return Spliterators.spliteratorUnknownSize(iterator(), - Spliterator.IMMUTABLE | - Spliterator.ORDERED); + default ImmutableList remove(ImmutableList elems) { + ImmutableList list = this; + for (E elem : elems) { + list = list.remove(elem); + } + return list; } /** - * Returns a sequential Stream with this collection as its source. + * Returns a new list without all the elements of the specified + * elements from this list. * - * @return a sequential Stream over the elements in this collection + * @param elems - elements to be removed from this list, if present + * @return a new list without all the elements of the specified + * elements from this list */ - default Stream stream() { - return StreamSupport.stream(spliterator(), false); + default ImmutableList remove(Collection elems) { + ImmutableList list = this; + for (E elem : elems) { + list = list.remove(elem); + } + return list; } /** - * Returns a parallel Stream with this collection as its source. + * Returns a new list without all the element of the specified elements + * from this list * - * @return a parallel Stream over the elements in this collection + * @param elems - elements to be removed from this list, if present + * @return a new list without all the element of the specified elements + * from this list */ - default Stream parallelStream() { - return StreamSupport.stream(spliterator(), true); + @SuppressWarnings({"unchecked"}) + default ImmutableList remove(E... elems) { + ImmutableList list = this; + for (int i = 0 ; i asList() { - List myList = new ArrayList(); - for (E e : this){ - myList.add(e); - } - return myList; - } - - public ImmutableList clone(); + * Returns a new list without the first occurrence of the specified + * element from this list. + * + * @param elem - element to be removed from this list, if present + * @return a new list without the first occurrence of the specified + * element from this list + */ + @SuppressWarnings("unchecked") + default ImmutableList remove(E elem) throws IllegalArgumentException { + E[] newElems; + int i; + boolean remove; + newElems = (E[]) new Object[size() - 1]; + i = 0; + remove = false; + for (E e : this) { + if(!remove && ImmutableCoreList.equals(elem, e)) + remove = true; + else{ + if (i == this.size()-1) + throw new IllegalArgumentException(); + newElems[i] = e; + i++; + } + } - // To be used for the clone() method in concrete classes (since Object - // methods cannot be overriden with the default keyword) - static ImmutableList clone(ImmutableList list) { - return list.create(list.asList()); - } + return create(newElems); + } /** - * Compares the specified object with this list for equality. Returns true - * if and only if the specified object is also a list, both lists have the - * same size, and all corresponding pairs of elements in the two lists are - * equal. (Two elements e1 and e2 are equal if - * (e1==null ? e2==null : e1.equals(e2)).) In other words, two - * lists are defined to be equal if they contain the same elements in the - * same order. This definition ensures that the equals method works properly - * across different implementations of the ImmutableList interface. + * Returns a new list without the element at the specified position in + * this list. * - * @param o the object to be compared for equality with this list - * @return if the specified object is equal to this list + * @param index - the index of the element to be removed + * @return a new list without the element at the specified position in + * this list */ - boolean equals(Object o); + ImmutableList remove(int index) throws ArrayIndexOutOfBoundsException; - // To be used for the equals() method in concrete classes (since Object + // To be used for the clone() method in concrete classes (since Object // methods cannot be overriden with the default keyword) - static boolean equals(ImmutableList list, Object o) { - if (! (o instanceof ImmutableList)) - return false; + static ImmutableList clone(ImmutableList list) { + return list.subList(0, list.size()); + } - @SuppressWarnings("rawtypes") - ImmutableList other = (ImmutableList) o; + default ImmutableList tail() throws UnsupportedOperationException { + if (isEmpty()) + throw new UnsupportedOperationException(); + else + return subList(1, size()); + } - Iterator it1 = list.iterator(); - @SuppressWarnings("rawtypes") Iterator it2 = other.iterator(); - while (it1.hasNext() && it2.hasNext()) { - if (!equals(it1.next(), it2.next())) - return false; - } - if (it1.hasNext() || it2.hasNext()) - return false; + default E head() throws NoSuchElementException { + if (isEmpty()) + throw new NoSuchElementException(); + else + return get(0); + } - return true; - } + default E last() throws NoSuchElementException { + if (isEmpty()) + throw new NoSuchElementException(); + else + return get(size()-1); + } - /** - * Hash an object. - * - * @param o the object to hash - * @return o1 == null ? 0 : o1.hashCode() - */ - static int hashCode(Object o) { - return o == null ? 0 : o.hashCode(); - } + @SuppressWarnings("unchecked") + default ImmutableList map(Function mapper) { + return (ImmutableList) InductiveList.super.map(mapper); + } - public int hashCode(); + default ImmutableList filter(Predicate predicate) { + return (ImmutableList) InductiveList.super.filter(predicate); + } - // To be used for the hashCode() method in concrete classes (since Object - // methods cannot be overriden with the default keyword) - static int hashCode(ImmutableList list) { - int hashCode = 1; - Iterator itr = list.iterator(); - while (itr.hasNext()) - hashCode = 31 * hashCode + hashCode(itr.next()); - return hashCode; - } + ImmutableList cons(E elem); } diff --git a/Immutable_collections_java8_project/src/collections/interfaces/InductiveIterativeList.java b/Immutable_collections_java8_project/src/collections/interfaces/InductiveIterativeList.java deleted file mode 100644 index 357d48f..0000000 --- a/Immutable_collections_java8_project/src/collections/interfaces/InductiveIterativeList.java +++ /dev/null @@ -1,235 +0,0 @@ -package collections.interfaces; - -import java.util.Collection; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.NoSuchElementException; - -public interface InductiveIterativeList extends InductiveList, - IterativeList { - - public InductiveIterativeList create(E[] elems); - - /** - * Returns a portion of this list. - * - * @param fromIndex low endpoint (inclusive) of the subList - * @param toIndex high endpoint (exclusive) of the subList - * @returns a portion of this list - * @throws IndexOutOfBoundsException if an endpoint index value is out - * of range (fromIndex < 0 || toIndex > size) - * @throws IllegalArgumentException if the endpoint indices are out of - * order (fromIndex > toIndex) - */ - InductiveIterativeList subList(int fromIndex, int toIndex) throws - IndexOutOfBoundsException, - IllegalArgumentException; - - /** - * Returns a new list with the elements of this list in reverse order. - * - * @return a new list with the elements of this list in reverse order. - */ - default InductiveIterativeList reverse() { - if (isEmpty()) - return this; - else - return tail().reverse().concat(head()); - } - - /** - * Returns a new list containing the elements from this list followed by - * the elements from the given list. - * - * @param elems the list to be concatened with - * @returns a new list containing the elements from this list followed - * by the elements from the given list - */ - default InductiveIterativeList concat(Collection elems) { - InductiveIterativeList list = this; - for (E elem : elems){ - list = list.concat(elem); - } - return list; - } - - /** - * Returns a new list containing the elements from this list followed by - * the elements from the given list. - * - * @param elems the list to be concatened with - * @returns a new list containing the elements from this list followed - * by the elements from the given list - */ - default InductiveIterativeList concat(InductiveIterativeList elems) { - InductiveIterativeList list = this; - for (E elem : elems){ - list = list.concat(elem); - } - return list; - } - - /** - * Returns a new list containing the elements from this list followed by - * the elements from the given list. - * - * @param elems the list to be concatened with - * @returns a new list containing the elements from this list followed - * by the elements from the given list - */ - @SuppressWarnings({"unchecked"}) - default InductiveIterativeList concat(E... elems) { - InductiveIterativeList list = this; - for (int i = 0 ; i concat(E elem) { - @SuppressWarnings("unchecked") - E[] elems = (E[]) new Object[size() + 1]; - int i = 0; - for (E e : this) { - elems[i] = e; - ++i; - } - elems[size()] = elem; - return create(elems); - } - - /** - * Returns a new list without all the elements of the specified - * elements from this list. - * - * @param elems - elements to be removed from this list, if present - * @return a new list without all the elements of the specified - * elements from this list - */ - default InductiveIterativeList remove(InductiveIterativeList elems) { - InductiveIterativeList list = this; - for (E elem : elems) { - list = list.remove(elem); - } - return list; - } - - /** - * Returns a new list without all the elements of the specified - * elements from this list. - * - * @param elems - elements to be removed from this list, if present - * @return a new list without all the elements of the specified - * elements from this list - */ - default InductiveIterativeList remove(Collection elems) { - InductiveIterativeList list = this; - for (E elem : elems) { - list = list.remove(elem); - } - return list; - } - - /** - * Returns a new list without all the element of the specified elements - * from this list - * - * @param elems - elements to be removed from this list, if present - * @return a new list without all the element of the specified elements - * from this list - */ - @SuppressWarnings({"unchecked"}) - default InductiveIterativeList remove(E... elems) { - InductiveIterativeList list = this; - for (int i = 0 ; i remove(E elem) throws IllegalArgumentException { - E[] newElems; - int i; - boolean remove; - newElems = (E[]) new Object[size() - 1]; - i = 0; - remove = false; - for (E e : this) { - if(!remove && ImmutableList.equals(elem, e)) - remove = true; - else{ - if (i == this.size()-1) - throw new IllegalArgumentException(); - newElems[i] = e; - i++; - } - } - - return create(newElems); - } - - /** - * Returns a new list without the element at the specified position in - * this list. - * - * @param index - the index of the element to be removed - * @return a new list without the element at the specified position in - * this list - */ - InductiveIterativeList remove(int index) throws ArrayIndexOutOfBoundsException; - - // To be used for the clone() method in concrete classes (since Object - // methods cannot be overriden with the default keyword) - static InductiveIterativeList clone(InductiveIterativeList list) { - return list.subList(0, list.size()); - } - - default InductiveIterativeList tail() throws UnsupportedOperationException { - if (isEmpty()) - throw new UnsupportedOperationException(); - else - return subList(1, size()); - } - - - default E head() throws NoSuchElementException { - if (isEmpty()) - throw new NoSuchElementException(); - else - return get(0); - } - - default E last() throws NoSuchElementException { - if (isEmpty()) - throw new NoSuchElementException(); - else - return get(size()-1); - } - - default InductiveIterativeList map(Function mapper) { - return (InductiveIterativeList) InductiveList.super.map(mapper); - } - - default InductiveIterativeList filter(Predicate predicate) { - return (InductiveIterativeList) InductiveList.super.filter(predicate); - } - - InductiveIterativeList cons(E elem); -} diff --git a/Immutable_collections_java8_project/src/collections/interfaces/InductiveList.java b/Immutable_collections_java8_project/src/collections/interfaces/InductiveList.java index 5127781..3e0a155 100644 --- a/Immutable_collections_java8_project/src/collections/interfaces/InductiveList.java +++ b/Immutable_collections_java8_project/src/collections/interfaces/InductiveList.java @@ -4,7 +4,7 @@ import java.util.function.Predicate; import java.util.NoSuchElementException; -public interface InductiveList extends ImmutableList { +public interface InductiveList extends ImmutableCoreList { //TODO ERROR : No isEmpty() method. /** * Return a new list with the elements of this list appended to given element. @@ -38,11 +38,12 @@ public interface InductiveList extends ImmutableList { */ E last() throws NoSuchElementException; - default InductiveList map(Function mapper) { - return (InductiveList) ImmutableList.super.map(mapper); + @SuppressWarnings("unchecked") + default InductiveList map(Function mapper) { + return (InductiveList) ImmutableCoreList.super.map(mapper); } - default InductiveList filter(Predicate predicate) { - return (InductiveList) ImmutableList.super.filter(predicate); + default InductiveList filter(Predicate predicate) { + return (InductiveList) ImmutableCoreList.super.filter(predicate); } } diff --git a/Immutable_collections_java8_project/src/collections/interfaces/IterativeList.java b/Immutable_collections_java8_project/src/collections/interfaces/IterativeList.java index 0508006..b8ba2c1 100644 --- a/Immutable_collections_java8_project/src/collections/interfaces/IterativeList.java +++ b/Immutable_collections_java8_project/src/collections/interfaces/IterativeList.java @@ -6,7 +6,7 @@ import java.util.function.Function; import java.util.function.Predicate; -public interface IterativeList extends ImmutableList { +public interface IterativeList extends ImmutableCoreList { default boolean isEmpty() { return size() == 0; @@ -27,29 +27,30 @@ default boolean isEmpty() { */ E get(int index) throws IndexOutOfBoundsException; - default Spliterator spliterator() { + default Spliterator spliterator() { return Spliterators.spliterator(iterator(), - size(), - Spliterator.IMMUTABLE | - Spliterator.ORDERED | - Spliterator.SIZED | - Spliterator.SUBSIZED); + size(), + Spliterator.IMMUTABLE | + Spliterator.ORDERED | + Spliterator.SIZED | + Spliterator.SUBSIZED); } public boolean equals(Object o); // To be used for the equals() method in concrete classes (since Object - // methods cannot be overriden with the default keyword) - static boolean equals(IterativeList list, Object o) { + // methods cannot be overridden with the default keyword) + @SuppressWarnings("unchecked") + static boolean equals(IterativeList list, Object o) { if (o instanceof IterativeList) - return list.equals((IterativeList)o); - else if (o instanceof ImmutableList) - return ImmutableList.equals(list, o); + return list.equals((IterativeList)o); + else if (o instanceof ImmutableCoreList) + return ImmutableCoreList.equals(list, o); else return false; } - default public boolean equals(IterativeList other) { + default public boolean equals(IterativeList other) { if (size() != other.size()) return false; @@ -58,7 +59,7 @@ default public boolean equals(IterativeList other) { Iterator it2 = other.iterator(); while (it1.hasNext()) { - if (!ImmutableList.equals(it1.next(), it2.next())) + if (!ImmutableCoreList.equals(it1.next(), it2.next())) //TODO return false; } @@ -66,15 +67,16 @@ default public boolean equals(IterativeList other) { } @SuppressWarnings({ "unchecked"}) - default E[] toArray() { + default E[] toArray() { return toArray((E[]) new Object[size()]); } - default IterativeList map(Function mapper) { - return (IterativeList) ImmutableList.super.map(mapper); + @SuppressWarnings("unchecked") + default IterativeList map(Function mapper) { + return (IterativeList) ImmutableCoreList.super.map(mapper); } - default IterativeList filter(Predicate predicate) { - return (IterativeList) ImmutableList.super.filter(predicate); + default IterativeList filter(Predicate predicate) { + return (IterativeList) ImmutableCoreList.super.filter(predicate); } } diff --git a/Immutable_collections_java8_project/src/main/Benchmarks.java b/Immutable_collections_java8_project/src/main/Benchmarks.java index 6a84780..73142ea 100644 --- a/Immutable_collections_java8_project/src/main/Benchmarks.java +++ b/Immutable_collections_java8_project/src/main/Benchmarks.java @@ -7,15 +7,15 @@ import collections.implementations.ImmutableArrayList; import collections.implementations.ImmutableLinkedList; -import collections.interfaces.InductiveIterativeList; +import collections.interfaces.ImmutableList; public class Benchmarks { - InductiveIterativeList ill; /** ImmutableLinkedList implementation */ - InductiveIterativeList ial; /** ImmutableArrayList implementation */ + ImmutableList ill; /** ImmutableLinkedList implementation */ + ImmutableList ial; /** ImmutableArrayList implementation */ List ll; /** LinkedList implementation */ List al; /** ArrayList implementation */ - InductiveIterativeList hial; /** Half ImmutableLinkedList implementation */ + ImmutableList hial; /** Half ImmutableLinkedList implementation */ List dummy; /** List implementation needed to concat */ public Benchmarks(int size) @@ -79,10 +79,10 @@ public void runHalfImmuLinkedListBench(int warmup, int maxIterations) } - - - - private void execAll(InductiveIterativeList list, int warmup, int maxIterations) + + + + private void execAll(ImmutableList list, int warmup, int maxIterations) { long execTime = 0; @@ -117,11 +117,11 @@ private void execAll(List list, int warmup, int maxIterations) } - - - - - private long execGet(InductiveIterativeList list, int warmup, int maxIterations) + + + + + private long execGet(ImmutableList list, int warmup, int maxIterations) { long beg = 0; long end = 0; @@ -165,7 +165,7 @@ private long execGet(List list, int warmup, int maxIterations) return (execTime/warmup); } - private long execSize(InductiveIterativeList list, int warmup, int maxIterations) + private long execSize(ImmutableList list, int warmup, int maxIterations) { long beg = 0; long end = 0; @@ -207,7 +207,7 @@ private long execSize(List list, int warmup, int maxIterations) return (execTime/warmup); } - private long execIndexOf(InductiveIterativeList list, int warmup, int maxIterations) + private long execIndexOf(ImmutableList list, int warmup, int maxIterations) { long beg = 0; long end = 0; @@ -252,12 +252,12 @@ private long execIndexOf(List list, int warmup, int maxIterations) } - private long execConcat(InductiveIterativeList list, int warmup, int maxIterations) + private long execConcat(ImmutableList list, int warmup, int maxIterations) { long beg = 0; long end = 0; @SuppressWarnings("unused") - InductiveIterativeList out; + ImmutableList out; long execTime = 0; for(int i=0; i < warmup; ++i) @@ -279,18 +279,18 @@ private long execConcat(List list, int warmup, int maxIterations) long beg = 0; long end = 0; long execTime = 0; - - for(int i=0; i < warmup; ++i) - { - beg = System.currentTimeMillis(); - for(int ite=0; ite < maxIterations; ++ite) - { - list.addAll((Collection) this.dummy); - } - end = System.currentTimeMillis(); - execTime += (end-beg); - list.removeAll(this.dummy); - } + + for(int i=0; i < warmup; ++i) + { + beg = System.currentTimeMillis(); + for(int ite=0; ite < maxIterations; ++ite) + { + list.addAll((Collection) this.dummy); + } + end = System.currentTimeMillis(); + execTime += (end-beg); + list.removeAll(this.dummy); + } return (execTime/warmup); } } diff --git a/Immutable_collections_java8_project/src/test/DoubleLinkedListProxyTest.java b/Immutable_collections_java8_project/src/test/DoubleLinkedListProxyTest.java index eca96e9..07752a6 100644 --- a/Immutable_collections_java8_project/src/test/DoubleLinkedListProxyTest.java +++ b/Immutable_collections_java8_project/src/test/DoubleLinkedListProxyTest.java @@ -3,22 +3,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collections; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.stream.Stream; +import org.junit.Before; import org.junit.Test; -import collections.implementations.*; +import collections.implementations.DoubleLinkedListProxy; public class DoubleLinkedListProxyTest { diff --git a/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java b/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java index 2b6e1e2..56ba83a 100644 --- a/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java +++ b/Immutable_collections_java8_project/src/test/ImmutableLinkedListTest.java @@ -1,21 +1,6 @@ package test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Stream; -import java.util.NoSuchElementException; -import java.util.Optional; - import org.junit.Before; -import org.junit.Test; - -import collections.implementations.ImmutableLinkedList; -import collections.interfaces.ImmutableList; public class ImmutableLinkedListTest extends InductiveIterativeListTest { diff --git a/Immutable_collections_java8_project/src/test/InductiveIterativeListTest.java b/Immutable_collections_java8_project/src/test/InductiveIterativeListTest.java index 6873a6b..7d9b942 100644 --- a/Immutable_collections_java8_project/src/test/InductiveIterativeListTest.java +++ b/Immutable_collections_java8_project/src/test/InductiveIterativeListTest.java @@ -4,9 +4,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Collections; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -18,51 +18,51 @@ import collections.implementations.ImmutableArrayList; import collections.implementations.ImmutableLinkedList; -import collections.interfaces.InductiveIterativeList; +import collections.interfaces.ImmutableList; interface ImmutableListFactory { - @SuppressWarnings("unchecked") public InductiveIterativeList create(E... elems); - public InductiveIterativeList create(); + @SuppressWarnings("unchecked") public ImmutableList create(E... elems); + public ImmutableList create(); } class ImmutableLinkedListFactory implements ImmutableListFactory { @SuppressWarnings({"unchecked"}) - public InductiveIterativeList create(E... elems) { + public ImmutableList create(E... elems) { return new ImmutableLinkedList(elems); } - public InductiveIterativeList create() { + public ImmutableList create() { return new ImmutableLinkedList(); } } class ImmutableArrayListFactory implements ImmutableListFactory { @SuppressWarnings({"unchecked"}) - public InductiveIterativeList create(E... elems) { + public ImmutableList create(E... elems) { return new ImmutableArrayList(elems); } - public InductiveIterativeList create() { + public ImmutableList create() { return new ImmutableArrayList(); } } class ReversedArrayListFactory implements ImmutableListFactory { @SuppressWarnings("unchecked") - public InductiveIterativeList create(E... _elems) { + public ImmutableList create(E... _elems) { List tmp = Arrays.asList(_elems); Collections.reverse(tmp); E[] elems = (E[]) tmp.toArray(); return new ImmutableArrayList(elems).reverse(); } - public InductiveIterativeList create() { + public ImmutableList create() { return new ImmutableArrayList().reverse(); } } public abstract class InductiveIterativeListTest { - protected InductiveIterativeList list; - protected InductiveIterativeList emptyList; + protected ImmutableList list; + protected ImmutableList emptyList; protected ImmutableListFactory factory; public void setUp(ImmutableListFactory factory) { @@ -108,10 +108,10 @@ public void SizeTest() { @Test public void SubListTest() { - InductiveIterativeList empty = list.subList(0, 0); + ImmutableList empty = list.subList(0, 0); assertTrue(empty.isEmpty()); - InductiveIterativeList subList = list.subList(1, 3); + ImmutableList subList = list.subList(1, 3); assertEquals(2, subList.size()); assertEquals(2, (int)subList.get(0)); assertEquals(3, (int)subList.get(1)); @@ -134,7 +134,7 @@ public void SubListExceptionTest3() { @Test public void MapTest() { - InductiveIterativeList mappedList = list.map((Integer x) -> x * 2); + ImmutableList mappedList = list.map((Integer x) -> x * 2); assertEquals(mappedList.size(), list.size()); assertEquals((int)mappedList.get(0), (int)2 * list.get(0)); assertEquals((int)mappedList.get(1), (int)2 * list.get(1)); @@ -143,7 +143,7 @@ public void MapTest() { @Test public void FilterTest() { - InductiveIterativeList filteredList = list.filter((Integer x) -> x % 2 != 0); + ImmutableList filteredList = list.filter((Integer x) -> x % 2 != 0); assertEquals(filteredList, new ImmutableLinkedList(1, 3)); filteredList = list.filter((Integer x) -> true); @@ -213,11 +213,11 @@ public void SubListIteratorTest() { // Test that iterators stop at the right last element for sublists // (since they all share their structures with a superlist) - InductiveIterativeList subList = list.subList(1, list.size()-1); + ImmutableList subList = list.subList(1, list.size()-1); assertEquals(1, subList.size()); int sizeWhenIterating = 0; - for (Integer i : subList) + for (@SuppressWarnings("unused") Integer i : subList) ++sizeWhenIterating; assertEquals(subList.size(), sizeWhenIterating); @@ -425,7 +425,7 @@ public void LastExceptionTest() { @Test public void TailTest() { - InductiveIterativeList tail = list.tail(); + ImmutableList tail = list.tail(); assertEquals(2, (int)tail.get(0)); assertEquals(3, (int)tail.get(1)); assertEquals(2, tail.size()); From 953b629264ccd4fc4e736b5b4f81bc8f639da4ce Mon Sep 17 00:00:00 2001 From: Theophile Morin Date: Thu, 12 Jun 2014 13:57:37 +0200 Subject: [PATCH 09/14] Removed abstract classes. --- ...t.java => ImmutableBaseInductiveList.java} | 22 +++++++++++- ...t.java => ImmutableBaseIterativeList.java} | 35 ++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) rename Immutable_collections_java8_project/src/collections/implementations/{ImmutableAbstractInductiveList.java => ImmutableBaseInductiveList.java} (75%) rename Immutable_collections_java8_project/src/collections/implementations/{ImmutableAbstractIterativeList.java => ImmutableBaseIterativeList.java} (52%) diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractInductiveList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java similarity index 75% rename from Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractInductiveList.java rename to Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java index 0de4cb0..64b2fc3 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractInductiveList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java @@ -1,11 +1,13 @@ package collections.implementations; +import java.util.Collection; +import java.util.Iterator; import java.util.NoSuchElementException; import collections.interfaces.ImmutableCoreList; import collections.interfaces.InductiveList; -public abstract class ImmutableAbstractInductiveList implements InductiveList { +public class ImmutableBaseInductiveList implements InductiveList { @Override public boolean isEmpty() { @@ -46,4 +48,22 @@ public InductiveList tail() throws UnsupportedOperationException { //TODO ERR public E last() throws NoSuchElementException { //TODO implementation class call an accessor method, check it. return null; } + + @Override + public ImmutableCoreList create(E[] elems) { + // TODO Auto-generated method stub + return null; + } + + @Override + public ImmutableCoreList create(Collection elems) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterator iterator() { + // TODO Auto-generated method stub + return null; + } } diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractIterativeList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java similarity index 52% rename from Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractIterativeList.java rename to Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java index 89736c9..36913af 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableAbstractIterativeList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java @@ -1,9 +1,12 @@ package collections.implementations; +import java.util.Collection; +import java.util.Iterator; + import collections.interfaces.ImmutableCoreList; import collections.interfaces.IterativeList; -public abstract class ImmutableAbstractIterativeList implements IterativeList +public class ImmutableBaseIterativeList implements IterativeList { @Override @@ -26,4 +29,34 @@ public int hashCode() { return ImmutableCoreList.hashCode(this); //TODO check "this" validity (abstract class) } + @Override + public ImmutableCoreList create(E[] elems) { + // TODO Auto-generated method stub + return null; + } + + @Override + public ImmutableCoreList create(Collection elems) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isEmpty() { + // TODO Auto-generated method stub + return false; + } + + @Override + public Iterator iterator() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int size() { + // TODO Auto-generated method stub + return 0; + } + } From d3a7d84b2fcc740de5a7f8e2c9570a607f1f2826 Mon Sep 17 00:00:00 2001 From: Thibault Date: Thu, 12 Jun 2014 15:01:01 +0200 Subject: [PATCH 10/14] Implementation de BaseInductive --- .../ImmutableBaseInductiveList.java | 174 ++++++++++++++++-- .../ImmutableBaseIterativeList.java | 1 + .../implementations/ImmutableLinkedList.java | 110 ++--------- 3 files changed, 178 insertions(+), 107 deletions(-) diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java index 64b2fc3..f3d5032 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java @@ -6,12 +6,87 @@ import collections.interfaces.ImmutableCoreList; import collections.interfaces.InductiveList; +class Node { + + /** The element in the list */ + private final E element; + + /** The next list node, null if this is last */ + private final Node next; + + public Node(E element, Node next) { + this.element=element; + this.next=next; + } + + public Node(E element) { + this(element, null); + } + + /** + * Returns the element in the node. + * + * @returns the element in the node. + */ + public E getElement() { + return this.element; + } + + /** Returns the next list node, null if this is last. + * + * @returns the next list node, null if this is last + */ + public Node getNext() { + return next; + } + + /** Returns whether this node is followed by another one. + * + * @returns true if this node is followed by another one. + */ + public boolean hasNext() { + return getNext() != null; + } +} public class ImmutableBaseInductiveList implements InductiveList { + + /** The first node element of the list. */ + private final Node head; - @Override - public boolean isEmpty() { - return false; //TODO find why this method is not implemented in concrete class (ImmutableLinkedList). + /** The last node element of the list. */ + private final Node last; + + /** The number of elements in this list. */ + private final int size; + + + public ImmutableBaseInductiveList(Node head, Node last, int size) { + this.head = head; + this.last = last; + this.size = size; + } + + /** + * Returns the first node element of the list. + * + * @returns the first node element of the list. + **/ + private Node headNode() { + return head; + } + + /** + * Returns the last node element of the list. + * + * @returns the last node element of the list. + **/ + private Node lastNode() { + return last; + } + + private int size() { + return size; } @Override @@ -31,39 +106,106 @@ public int hashCode() { @Override public InductiveList cons(E elem) { - return null; // new ImmutableLinkedList(new Node(elem, head()), last(), size() + 1); //TODO add size in Core ? + return new ImmutableBaseInductiveList(new Node(elem, headNode()), + lastNode(), + size() + 1); } @Override - public E head() throws NoSuchElementException { //TODO implementation class call an accessor method, check it. - return null; + public E head() throws NoSuchElementException { + if (isEmpty()) + throw new NoSuchElementException(); + else + return headNode().getElement(); } + @SuppressWarnings("unchecked") @Override - public InductiveList tail() throws UnsupportedOperationException { //TODO ERROR : check why tail is not implemented in the implementation class... - return null; + public InductiveList tail() { + + int i = 1; + Node node = headNode().getNext(); + Node subListHead = headNode().getNext(); + + while (i != this.size-1) { + node = node.getNext(); + ++i; + } + Node subListLast = node; + + return new ImmutableBaseInductiveList(subListHead, + subListLast, + this.size - 1); } @Override - public E last() throws NoSuchElementException { //TODO implementation class call an accessor method, check it. - return null; + public E last() throws NoSuchElementException { + if (isEmpty()) + throw new NoSuchElementException(); + else + return lastNode().getElement(); } @Override public ImmutableCoreList create(E[] elems) { - // TODO Auto-generated method stub - return null; + return new ImmutableLinkedList(elems); } @Override public ImmutableCoreList create(Collection elems) { - // TODO Auto-generated method stub - return null; + return new ImmutableLinkedList(elems); } @Override public Iterator iterator() { - // TODO Auto-generated method stub - return null; + return new ImmutableLinkedListIterator(); + } + + @Override + public boolean isEmpty() { + return head==null; + } + + // Iterators & streams + + class ImmutableLinkedListIterator implements Iterator { + + /** Current node pointed by the iterator */ + private Node currentNode; + + /** Tell whether the iterator can continue or not */ + private boolean hasNext; + + /** + * Create a new iterator starting from the beginning of the linked list. + */ + public ImmutableLinkedListIterator() { + currentNode = headNode(); + hasNext = (size() != 0); + } + + public boolean hasNext() { + return hasNext; + } + + public E next() throws NoSuchElementException { + if (!hasNext()) + throw new NoSuchElementException(); + + E elem = currentNode.getElement(); + if (currentNode == lastNode()) + hasNext = false; + else + currentNode = currentNode.getNext(); + return elem; + } + + public void remove() throws + UnsupportedOperationException, + IllegalStateException { + throw new UnsupportedOperationException(); + } } } + + diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java index 36913af..5f552ab 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java @@ -6,6 +6,7 @@ import collections.interfaces.ImmutableCoreList; import collections.interfaces.IterativeList; + public class ImmutableBaseIterativeList implements IterativeList { diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java index 2013b09..c7ee6df 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java @@ -6,51 +6,9 @@ import collections.interfaces.ImmutableCoreList; import collections.interfaces.ImmutableList; +import collections.interfaces.InductiveList; import collections.interfaces.IterativeList; -class Node { - - /** The element in the list */ - private final E element; - - /** The next list node, null if this is last */ - private final Node next; - - public Node(E element, Node next) { - this.element=element; - this.next=next; - } - - public Node(E element) { - this(element, null); - } - - /** - * Returns the element in the node. - * - * @returns the element in the node. - */ - public E getElement() { - return this.element; - } - - /** Returns the next list node, null if this is last. - * - * @returns the next list node, null if this is last - */ - public Node getNext() { - return next; - } - - /** Returns whether this node is followed by another one. - * - * @returns true if this node is followed by another one. - */ - public boolean hasNext() { - return getNext() != null; - } -} - public class ImmutableLinkedList implements ImmutableList { /** The first node element of the list. */ @@ -244,60 +202,30 @@ public ImmutableLinkedList remove(int index) { return new ImmutableLinkedList(newElems); } - // Iterators & streams - - class ImmutableLinkedListIterator implements Iterator { - - /** Current node pointed by the iterator */ - private Node currentNode; - - /** Tell whether the iterator can continue or not */ - private boolean hasNext; - - /** - * Create a new iterator starting from the beginning of the linked list. - */ - public ImmutableLinkedListIterator() { - currentNode = headNode(); - hasNext = (size() != 0); - } - - public boolean hasNext() { - return hasNext; - } - - public E next() throws NoSuchElementException { - if (!hasNext()) - throw new NoSuchElementException(); - - E elem = currentNode.getElement(); - if (currentNode == lastNode()) - hasNext = false; - else - currentNode = currentNode.getNext(); - return elem; - } - - public void remove() throws - UnsupportedOperationException, - IllegalStateException { - throw new UnsupportedOperationException(); - } + @Override + public ImmutableList tail() throws UnsupportedOperationException { + // TODO Auto-generated method stub + return null; } - public Iterator iterator() { - return new ImmutableLinkedListIterator(); + @Override + public boolean isEmpty() { + // TODO Auto-generated method stub + return false; } - public int hashCode() { - return ImmutableCoreList.hashCode(this); //TODO check call to first background interface while ImmutableList + @Override + public ImmutableCoreList clone() { + // TODO Auto-generated method stub + return null; } - public ImmutableList clone() { - return ImmutableList.clone(this); + @Override + public Iterator iterator() { + // TODO Auto-generated method stub + return null; } - public boolean equals(Object o) { - return IterativeList.equals(this, o); - } + + } From c92765eb4ba35df5a18f81b9ba54bc8cf0ec8e60 Mon Sep 17 00:00:00 2001 From: Thibault Date: Thu, 12 Jun 2014 15:09:34 +0200 Subject: [PATCH 11/14] Implementation BaseIterative --- .../ImmutableBaseIterativeList.java | 75 +++++++++++++++---- .../implementations/ImmutableLinkedList.java | 67 ++++++++++++----- 2 files changed, 108 insertions(+), 34 deletions(-) diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java index 5f552ab..6e554da 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java @@ -2,6 +2,7 @@ import java.util.Collection; import java.util.Iterator; +import java.util.NoSuchElementException; import collections.interfaces.ImmutableCoreList; import collections.interfaces.IterativeList; @@ -9,55 +10,99 @@ public class ImmutableBaseIterativeList implements IterativeList { + + private final E[] _array; + private final int _length; + + @SuppressWarnings("unchecked") + public ImmutableBaseIterativeList() + { + _array = (E[]) new Object[0]; + _length = 0; + } @Override public E get(int index) throws IndexOutOfBoundsException { - return null; //TODO refers to the implementation class + if (index < 0 || index >= size()) + throw new IndexOutOfBoundsException(); + if(index >=0 && index < size()) + return _array[index]; + else + return null; } @Override public boolean equals(Object o) { - return IterativeList.equals(this, o); //TODO check "this" validity (abstract class) + return IterativeList.equals(this, o); } @Override - public ImmutableCoreList clone() { //TODO check static returned type - return ImmutableCoreList.clone(this); //TODO check "this" validity (abstract class) + public ImmutableCoreList clone() { + return ImmutableCoreList.clone(this); } @Override public int hashCode() { - return ImmutableCoreList.hashCode(this); //TODO check "this" validity (abstract class) + return ImmutableCoreList.hashCode(this); } @Override public ImmutableCoreList create(E[] elems) { - // TODO Auto-generated method stub - return null; + return new ImmutableArrayList(elems); } @Override public ImmutableCoreList create(Collection elems) { - // TODO Auto-generated method stub - return null; + return new ImmutableArrayList(elems); } @Override public boolean isEmpty() { - // TODO Auto-generated method stub - return false; + return this._length==0; } @Override public Iterator iterator() { - // TODO Auto-generated method stub - return null; + return new ImmutableArrayListIterator(); } @Override public int size() { - // TODO Auto-generated method stub - return 0; + return _length; } + class ImmutableArrayListIterator implements Iterator { + + /** Current node pointed by the iterator */ + private int index; + private int size; + + /** + * Create a new iterator starting from the beginning of the list. + */ + public ImmutableArrayListIterator() { + index = 0; + size = size(); + } + + public boolean hasNext() { + return index <= size-1 ? true : false; + } + + public E next() throws NoSuchElementException { + if(index >= size) + throw new NoSuchElementException(); + + E elem = _array[index]; + ++index; + return elem; + } + + public void remove() throws + UnsupportedOperationException, + IllegalStateException { + throw new UnsupportedOperationException(); + } + } + } diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java index c7ee6df..8da54cf 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java @@ -6,7 +6,6 @@ import collections.interfaces.ImmutableCoreList; import collections.interfaces.ImmutableList; -import collections.interfaces.InductiveList; import collections.interfaces.IterativeList; public class ImmutableLinkedList implements ImmutableList { @@ -202,30 +201,60 @@ public ImmutableLinkedList remove(int index) { return new ImmutableLinkedList(newElems); } - @Override - public ImmutableList tail() throws UnsupportedOperationException { - // TODO Auto-generated method stub - return null; - } + // Iterators & streams - @Override - public boolean isEmpty() { - // TODO Auto-generated method stub - return false; - } + class ImmutableLinkedListIterator implements Iterator { + + /** Current node pointed by the iterator */ + private Node currentNode; + + /** Tell whether the iterator can continue or not */ + private boolean hasNext; + + /** + * Create a new iterator starting from the beginning of the linked list. + */ + public ImmutableLinkedListIterator() { + currentNode = headNode(); + hasNext = (size() != 0); + } + + public boolean hasNext() { + return hasNext; + } - @Override - public ImmutableCoreList clone() { - // TODO Auto-generated method stub - return null; + public E next() throws NoSuchElementException { + if (!hasNext()) + throw new NoSuchElementException(); + + E elem = currentNode.getElement(); + if (currentNode == lastNode()) + hasNext = false; + else + currentNode = currentNode.getNext(); + return elem; + } + + public void remove() throws + UnsupportedOperationException, + IllegalStateException { + throw new UnsupportedOperationException(); + } } - @Override public Iterator iterator() { - // TODO Auto-generated method stub - return null; + return new ImmutableLinkedListIterator(); } + public int hashCode() { + return ImmutableCoreList.hashCode(this); //TODO check call to first background interface while ImmutableList + } + + public ImmutableList clone() { + return ImmutableList.clone(this); + } - + public boolean equals(Object o) { + return IterativeList.equals(this, o); + } } From e61af35a1260caf102e55bbf802037e954c8ceaa Mon Sep 17 00:00:00 2001 From: Theophile Morin Date: Thu, 12 Jun 2014 16:19:09 +0200 Subject: [PATCH 12/14] ImmutableLinkedList refactoring --- .../ImmutableBaseInductiveList.java | 169 +++++++++++++----- .../implementations/ImmutableLinkedList.java | 136 ++++---------- 2 files changed, 154 insertions(+), 151 deletions(-) diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java index f3d5032..805ee5c 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseInductiveList.java @@ -6,6 +6,9 @@ import collections.interfaces.ImmutableCoreList; import collections.interfaces.InductiveList; + + + class Node { /** The element in the list */ @@ -49,30 +52,87 @@ public boolean hasNext() { } } -public class ImmutableBaseInductiveList implements InductiveList { - +public abstract class ImmutableBaseInductiveList implements InductiveList { + /** The first node element of the list. */ - private final Node head; + protected final Node head; /** The last node element of the list. */ - private final Node last; - + protected final Node last; + /** The number of elements in this list. */ - private final int size; + protected final int size; + /** + * Internal constructor which create a linked list given its attributes. + * + * @param head The first node of the list + * @param last The last node of the list + * @param size The size of the list + */ public ImmutableBaseInductiveList(Node head, Node last, int size) { this.head = head; this.last = last; this.size = size; } - + + /** + * Create a empty linked list. + */ + public ImmutableBaseInductiveList() { + this(null, null, 0); + } + + /** + * Create a linked list containing the given elements in order. + * + * @param elems collection of elements to populate this list from + * @throws NullPointerException if elems is null + */ + @SuppressWarnings("unchecked") + public ImmutableBaseInductiveList(Collection elems) { + this((E[])elems.toArray()); + } + + /** + * Create a linked list containing the given elements in order. + * + * @param elems the elements to populate this list from + * @throws NullPointerException if elems is null + */ + @SuppressWarnings({"unchecked"}) + public ImmutableBaseInductiveList(E... elems) { + if (elems == null) + throw new NullPointerException(); + + if (elems.length == 0) { + this.head = null; + this.last = null; + this.size = 0; + return; + } + + Node head = new Node(elems[elems.length - 1]); + this.last = head; + + for (int i = elems.length - 2 ; i >=0 ; --i) + head = new Node(elems[i], head); + + this.head = head; + this.size = elems.length; + } + + + + + /** * Returns the first node element of the list. * * @returns the first node element of the list. **/ - private Node headNode() { + protected Node headNode() { return head; } @@ -81,36 +141,36 @@ private Node headNode() { * * @returns the last node element of the list. **/ - private Node lastNode() { + protected Node lastNode() { return last; } - private int size() { + protected int size() { return size; } - + @Override - public ImmutableCoreList clone() { //TODO check static returned type. - return ImmutableCoreList.clone(this); //TODO check call + public InductiveList clone() { + return (InductiveList) ImmutableCoreList.clone(this); } - + @Override public boolean equals(Object o) { - return ImmutableCoreList.equals(this, o);//TODO check call to first background interface while InductiveList + return ImmutableCoreList.equals(this, o); } - + @Override public int hashCode() { - return ImmutableCoreList.hashCode(this); //TODO check call to first background interface while InductiveList + return ImmutableCoreList.hashCode(this); } - + @Override public InductiveList cons(E elem) { - return new ImmutableBaseInductiveList(new Node(elem, headNode()), - lastNode(), - size() + 1); + return create(new Node(elem, headNode()), + lastNode(), + size() + 1); } - + @Override public E head() throws NoSuchElementException { if (isEmpty()) @@ -118,26 +178,45 @@ public E head() throws NoSuchElementException { else return headNode().getElement(); } - - @SuppressWarnings("unchecked") - @Override - public InductiveList tail() { - int i = 1; - Node node = headNode().getNext(); - Node subListHead = headNode().getNext(); - while (i != this.size-1) { - node = node.getNext(); - ++i; + @Override + public InductiveList tail() { + if (isEmpty()) + throw new UnsupportedOperationException(); + else + { + final int fromIndex = 1; + final int toIndex = size(); + if (fromIndex < 0 || toIndex > size()) + throw new IndexOutOfBoundsException(); + if (fromIndex > toIndex) + throw new IllegalArgumentException(); + if (fromIndex == toIndex) + return new ImmutableLinkedList(); + + int i = 0; + Node node = headNode(); + while (i != fromIndex) { + node = node.getNext(); + ++i; + } + Node subListHead = node; + + while (i != toIndex-1) { + node = node.getNext(); + ++i; + } + Node subListLast = node; + + return create(subListHead, + subListLast, + toIndex - fromIndex); } - Node subListLast = node; - - return new ImmutableBaseInductiveList(subListHead, - subListLast, - this.size - 1); } - + + public abstract ImmutableLinkedList create(Node from, Node head, int size); + @Override public E last() throws NoSuchElementException { if (isEmpty()) @@ -146,29 +225,23 @@ public E last() throws NoSuchElementException { return lastNode().getElement(); } - @Override - public ImmutableCoreList create(E[] elems) { - return new ImmutableLinkedList(elems); - } - @Override - public ImmutableCoreList create(Collection elems) { - return new ImmutableLinkedList(elems); - } @Override public Iterator iterator() { return new ImmutableLinkedListIterator(); } + + @Override public boolean isEmpty() { return head==null; } - + // Iterators & streams - class ImmutableLinkedListIterator implements Iterator { + class ImmutableLinkedListIterator implements Iterator { //TODO change name ? /** Current node pointed by the iterator */ private Node currentNode; diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java index c7ee6df..6db34c4 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableLinkedList.java @@ -1,46 +1,12 @@ package collections.implementations; import java.util.Collection; -import java.util.Iterator; -import java.util.NoSuchElementException; -import collections.interfaces.ImmutableCoreList; import collections.interfaces.ImmutableList; -import collections.interfaces.InductiveList; -import collections.interfaces.IterativeList; -public class ImmutableLinkedList implements ImmutableList { +public class ImmutableLinkedList extends ImmutableBaseInductiveList implements ImmutableList{ - /** The first node element of the list. */ - private final Node head; - /** The last node element of the list. */ - private final Node last; - - /** The number of elements in this list. */ - private final int size; - - /** - * Returns the first node element of the list. - * - * @returns the first node element of the list. - **/ - private Node headNode() { - return head; - } - - /** - * Returns the last node element of the list. - * - * @returns the last node element of the list. - **/ - private Node lastNode() { - return last; - } - - public int size() { - return size; - } // Constructors @@ -52,9 +18,7 @@ public int size() { * @param size The size of the list */ private ImmutableLinkedList(Node head, Node last, int size) { - this.head = head; - this.last = last; - this.size = size; + super(head, last, size); } /** @@ -71,7 +35,7 @@ public ImmutableLinkedList() { * @throws NullPointerException if elems is null */ @SuppressWarnings("unchecked") - public ImmutableLinkedList(Collection elems) { + public ImmutableLinkedList(Collection elems) { this((E[])elems.toArray()); } @@ -83,36 +47,36 @@ public ImmutableLinkedList(Collection elems) { */ @SuppressWarnings({"unchecked"}) public ImmutableLinkedList(E... elems) { - if (elems == null) - throw new NullPointerException(); - - if (elems.length == 0) { - this.head = null; - this.last = null; - this.size = 0; - return; - } - - Node head = new Node(elems[elems.length - 1]); - this.last = head; + super(elems); + } - for (int i = elems.length - 2 ; i >=0 ; --i) - head = new Node(elems[i], head); - this.head = head; - this.size = elems.length; - } + @Override public ImmutableLinkedList create(E[] elems) { return new ImmutableLinkedList(elems); } + @Override public ImmutableLinkedList create(Collection elems) { return new ImmutableLinkedList(elems); } + @Override + public ImmutableLinkedList create(Node from, Node head, int size){ + return new ImmutableLinkedList(from, head, size); + } + + + // Operations + + public int size() { + return size; + } + + public E get(int index) throws IndexOutOfBoundsException { if (index < 0 || index >= size()) throw new IndexOutOfBoundsException(); @@ -127,23 +91,9 @@ public E get(int index) throws IndexOutOfBoundsException { return null; // Never happens } - public E head() throws NoSuchElementException { - if (isEmpty()) - throw new NoSuchElementException(); - else - return headNode().getElement(); - } - - public E last() throws NoSuchElementException { - if (isEmpty()) - throw new NoSuchElementException(); - else - return lastNode().getElement(); - } - public ImmutableLinkedList subList(int fromIndex, int toIndex) throws - IndexOutOfBoundsException, - IllegalArgumentException { + IndexOutOfBoundsException, + IllegalArgumentException { if (fromIndex < 0 || toIndex > size()) throw new IndexOutOfBoundsException(); @@ -167,17 +117,10 @@ public ImmutableLinkedList subList(int fromIndex, int toIndex) throws Node subListLast = node; return new ImmutableLinkedList(subListHead, - subListLast, - toIndex - fromIndex); + subListLast, + toIndex - fromIndex); } - // Factories - - public ImmutableLinkedList cons(E elem) { - return new ImmutableLinkedList(new Node(elem, headNode()), - lastNode(), - size() + 1); - } @SuppressWarnings("unchecked") public ImmutableLinkedList remove(int index) { @@ -202,30 +145,17 @@ public ImmutableLinkedList remove(int index) { return new ImmutableLinkedList(newElems); } - @Override - public ImmutableList tail() throws UnsupportedOperationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isEmpty() { - // TODO Auto-generated method stub - return false; - } - - @Override - public ImmutableCoreList clone() { - // TODO Auto-generated method stub - return null; + + @Override + public ImmutableLinkedList tail() { + return (ImmutableLinkedList) super.tail(); } + + @Override - public Iterator iterator() { - // TODO Auto-generated method stub - return null; - } - + public ImmutableLinkedList cons(E elem) { + return (ImmutableLinkedList) super.cons(elem); + } - } From cf0d8a125188caa899491f18f0eec6f6ee444d10 Mon Sep 17 00:00:00 2001 From: Theophile Morin Date: Thu, 12 Jun 2014 16:43:55 +0200 Subject: [PATCH 13/14] IterativeList refactoring --- .../implementations/ImmutableArrayList.java | 122 +++--------------- .../ImmutableBaseIterativeList.java | 80 +++++++++--- 2 files changed, 78 insertions(+), 124 deletions(-) diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java index e1f005b..54e11ab 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableArrayList.java @@ -1,27 +1,18 @@ package collections.implementations; import java.util.Collection; -import java.util.Iterator; -import java.util.NoSuchElementException; -import collections.interfaces.ImmutableCoreList; import collections.interfaces.ImmutableList; -import collections.interfaces.IterativeList; -public class ImmutableArrayList implements ImmutableList +public class ImmutableArrayList extends ImmutableBaseIterativeList implements ImmutableList { - private final E[] _array; - private final int _length; - /** * Constructs an empty list with an initial capacity of 0. */ - @SuppressWarnings("unchecked") public ImmutableArrayList () { - _array = (E[]) new Object[0]; - _length = 0; + super(); } /** @@ -32,26 +23,11 @@ public ImmutableArrayList () @SuppressWarnings("unchecked") public ImmutableArrayList (E... elems) { - if (elems == null) - throw new NullPointerException(); - else if (elems.length == 0) { - this._array = (E[]) new Object[0]; - this._length = 0; - } - else - { - _array = elems; - _length = _array.length; - } - } - - public ImmutableArrayList create(E[] elems) { - return new ImmutableArrayList(elems); - } - - public ImmutableArrayList create(Collection elems) { - return new ImmutableArrayList(elems); + super(elems); } + + + /** *

Constructs a list containing the elements of the specified @@ -62,77 +38,24 @@ public ImmutableArrayList create(Collection elems) { * * @param elems - the collection whose elements are to be placed into this list */ - @SuppressWarnings("unchecked") public ImmutableArrayList(Collection elems) { - if (elems == null) - throw new NullPointerException(); - else - { - _array = (E[])elems.toArray(); - _length = _array.length; - } + super(elems); } - /** - * Private accessor to get the inner array. - * @return the inner array. - */ - private E[] getArray() { - return _array; - } - - class ImmutableArrayListIterator implements Iterator { - - /** Current node pointed by the iterator */ - private int index; - private int size; - - /** - * Create a new iterator starting from the beginning of the list. - */ - public ImmutableArrayListIterator() { - index = 0; - size = size(); - } + + - public boolean hasNext() { - return index <= size-1 ? true : false; - } - - public E next() throws NoSuchElementException { - if(index >= size) - throw new NoSuchElementException(); - - E elem = getArray()[index]; - ++index; - return elem; - } - - public void remove() throws - UnsupportedOperationException, - IllegalStateException { - throw new UnsupportedOperationException(); - } + public ImmutableArrayList create(E[] elems) { + return new ImmutableArrayList(elems); } - public Iterator iterator() { - return new ImmutableArrayListIterator(); - + public ImmutableArrayList create(Collection elems) { + return new ImmutableArrayList(elems); } - public int size() { - return _length; - } - public E get(int index) { //TODO create an accessor for the _array and put the code into the absract class. - if (index < 0 || index >= size()) - throw new IndexOutOfBoundsException(); - if(index >=0 && index < size()) - return _array[index]; - else - return null; - } + @Override public ImmutableArrayList subList(int fromIndex, int toIndex) @@ -183,10 +106,7 @@ public ImmutableArrayList remove(int index) { return new ImmutableArrayList(newElems); } - public E[] toArray() { - return getArray(); - } - + public ImmutableArrayList cons(E elem) { @SuppressWarnings("unchecked") E[] elems = (E[]) new Object[size()+1]; @@ -202,15 +122,5 @@ public ImmutableArrayList cons(E elem) { } - public int hashCode() { - return ImmutableCoreList.hashCode(this); - } - - public ImmutableList clone() { - return ImmutableList.clone(this); - } - - public boolean equals(Object o) { - return IterativeList.equals(this, o); - } + } diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java index 6e554da..855e54a 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableBaseIterativeList.java @@ -8,12 +8,17 @@ import collections.interfaces.IterativeList; -public class ImmutableBaseIterativeList implements IterativeList +public abstract class ImmutableBaseIterativeList implements IterativeList { - private final E[] _array; - private final int _length; + protected final E[] _array; + protected final int _length; + + + /** + * Constructs an empty list with an initial capacity of 0. + */ @SuppressWarnings("unchecked") public ImmutableBaseIterativeList() { @@ -21,6 +26,60 @@ public ImmutableBaseIterativeList() _length = 0; } + /** + *

Constructs a list containing the given elements + *

If the specified collection is null, constructs an empty ArrayList with a capacity of 0. + * @param elems - the collection whose elements are to be placed into this list + */ + @SuppressWarnings("unchecked") + public ImmutableBaseIterativeList (E... elems) + { + if (elems == null) + throw new NullPointerException(); + else if (elems.length == 0) { + this._array = (E[]) new Object[0]; + this._length = 0; + } + else + { + _array = elems; + _length = _array.length; + } + } + + + /** + *

Constructs a list containing the elements of the specified + * collection, in the order they are returned by the collection's + * iterator. + *

If the specified collection is null, constructs an empty ArrayList + * with a capacity of 0. + * + * @param elems - the collection whose elements are to be placed into this list + */ + @SuppressWarnings("unchecked") + public ImmutableBaseIterativeList(Collection elems) + { + if (elems == null) + throw new NullPointerException(); + else + { + _array = (E[])elems.toArray(); + _length = _array.length; + } + } + + + /** + * Private accessor to get the inner array. + * @return the inner array. + */ + protected E[] getArray() { + return _array; + } + + + @Override public E get(int index) throws IndexOutOfBoundsException { if (index < 0 || index >= size()) @@ -46,21 +105,6 @@ public int hashCode() { return ImmutableCoreList.hashCode(this); } - @Override - public ImmutableCoreList create(E[] elems) { - return new ImmutableArrayList(elems); - } - - @Override - public ImmutableCoreList create(Collection elems) { - return new ImmutableArrayList(elems); - } - - @Override - public boolean isEmpty() { - return this._length==0; - } - @Override public Iterator iterator() { return new ImmutableArrayListIterator(); From 20489f7fbaeec60a182667caf9635b5b2457f42f Mon Sep 17 00:00:00 2001 From: Theophile Morin Date: Thu, 12 Jun 2014 16:46:50 +0200 Subject: [PATCH 14/14] Warnings removed --- .../implementations/ImmutableReversedArrayList.java | 4 ++-- .../src/collections/interfaces/ImmutableCoreList.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java b/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java index 38feff9..19a5ca5 100644 --- a/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java +++ b/Immutable_collections_java8_project/src/collections/implementations/ImmutableReversedArrayList.java @@ -52,7 +52,7 @@ public E last() throws NoSuchElementException { return list.head(); } - @SuppressWarnings("unchecked") + public ImmutableArrayList subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException, IllegalArgumentException { @@ -67,7 +67,7 @@ public ImmutableArrayList reverse() { return list; } - @SuppressWarnings("unchecked") + public ImmutableArrayList remove(int index) { return list.remove(reverseIndex(index)).reverse(); } diff --git a/Immutable_collections_java8_project/src/collections/interfaces/ImmutableCoreList.java b/Immutable_collections_java8_project/src/collections/interfaces/ImmutableCoreList.java index f6b660b..2c06f5d 100644 --- a/Immutable_collections_java8_project/src/collections/interfaces/ImmutableCoreList.java +++ b/Immutable_collections_java8_project/src/collections/interfaces/ImmutableCoreList.java @@ -237,7 +237,7 @@ default Stream parallelStream() { @SuppressWarnings("unchecked") default E[] toArray() { //TODO unused E elem int size = 0; - for ( E elem : this) + for ( @SuppressWarnings("unused") E elem : this) ++size; return toArray((E[]) new Object[size]); }