1 package de.fhdw.wtf.context.model.collections;
2
3 import java.util.Iterator;
4 import java.util.ListIterator;
5 import java.util.Vector;
6
7 import de.fhdw.wtf.context.exception.FrameworkException;
8 import de.fhdw.wtf.context.model.Anything;
9 import de.fhdw.wtf.context.model.collections.functors.EquivalenceRelation;
10 import de.fhdw.wtf.context.model.collections.functors.Function;
11 import de.fhdw.wtf.context.model.collections.functors.Operator;
12 import de.fhdw.wtf.context.model.collections.functors.Predicate;
13
14
15
16
17
18
19
20 public class ImmutableList<T extends Anything> implements ImmutableCollection<T> {
21
22
23
24
25 private final java.util.List<T> elements;
26
27
28
29
30 public ImmutableList() {
31 this.elements = new Vector<>();
32 }
33
34 @Override
35 public Collection<T> union(final Collection<? extends T> otherCollection) {
36 final ImmutableList<T> result = new ImmutableList<>();
37 result.elements.addAll(this.elements);
38 if (otherCollection instanceof ImmutableCollection) {
39 result.addImmutableCollection((ImmutableCollection<? extends T>) otherCollection);
40 } else if (otherCollection instanceof MutableCollection) {
41 result.addMutableCollection(otherCollection);
42 } else {
43 throw new FrameworkException("collection not supported");
44 }
45 return result;
46 }
47
48
49
50
51
52
53
54 private void addMutableCollection(final Collection<? extends T> otherCollection) {
55 final Iterator<? extends T> iterator = ((MutableCollection<? extends T>) otherCollection).iterator();
56 while (iterator.hasNext()) {
57 final T current = iterator.next();
58 this.elements.add(current);
59 }
60 }
61
62
63
64
65
66
67
68 private void addImmutableCollection(final ImmutableCollection<? extends T> otherCollection) {
69 if (!otherCollection.isEmpty()) {
70 this.elements.add(otherCollection.front());
71 this.addImmutableCollection(otherCollection.tail());
72 }
73 }
74
75 @Override
76 public boolean contains(final T element) {
77 return this.elements.contains(element);
78 }
79
80 @Override
81 public ImmutableCollection<T> add(final T element) {
82 final ImmutableList<T> result = new ImmutableList<>();
83 result.elements.addAll(this.elements);
84 result.elements.add(element);
85 return result;
86 }
87
88 @Override
89 public T front() {
90 return this.elements.get(0);
91 }
92
93 @Override
94 public ImmutableCollection<T> tail() {
95 final ImmutableList<T> result = new ImmutableList<>();
96 result.elements.addAll(this.elements);
97 result.elements.remove(0);
98 return result;
99 }
100
101 @Override
102 public ImmutableCollection<T> reverse() {
103 final ImmutableList<T> result = new ImmutableList<>();
104 final ListIterator<T> iterator = this.elements.listIterator(this.elements.size());
105 while (iterator.hasPrevious()) {
106 final T current = iterator.previous();
107 result.elements.add(current);
108 }
109 return result;
110 }
111
112 @Override
113 public <U extends Anything> ImmutableCollection<U> map(final Function<T, U> function) {
114 final ImmutableList<U> result = new ImmutableList<>();
115 final Iterator<T> iterator = this.elements.iterator();
116 while (iterator.hasNext()) {
117 final T current = iterator.next();
118 result.elements.add(function.f(current));
119 }
120 return result;
121 }
122
123 @Override
124 public <U extends Anything> U reduce(final Operator<T, U> aggregation) {
125 U result = aggregation.n();
126 final Iterator<T> iterator = this.elements.iterator();
127 while (iterator.hasNext()) {
128 final T current = iterator.next();
129 result = aggregation.add(result, current);
130 }
131 return result;
132 }
133
134 @Override
135 public <U extends Anything> ImmutableCollection<U> reduceEquivalent(final EquivalenceRelation<T> equi,
136 final Operator<T, U> aggregation) {
137 final Vector<ImmutableList<T>> between = new Vector<>();
138 final Iterator<T> outerIterator = this.elements.iterator();
139 while (outerIterator.hasNext()) {
140 final T current = outerIterator.next();
141 final ImmutableList<T> currentList = new ImmutableList<>();
142 final Iterator<T> innerIterator = this.elements.iterator();
143 while (innerIterator.hasNext()) {
144 final T innerCurrent = innerIterator.next();
145 if (equi.equivalent(current, innerCurrent)) {
146 currentList.add(innerCurrent);
147 }
148 }
149 between.add(currentList);
150 }
151 final ImmutableList<U> result = new ImmutableList<>();
152 while (!between.isEmpty()) {
153 final ImmutableList<T> current = between.get(0);
154 between.remove(0);
155 final Iterator<ImmutableList<T>> iterator = between.iterator();
156 while (iterator.hasNext()) {
157 final ImmutableList<T> innerCurrent = iterator.next();
158 if (innerCurrent.equals(current)) {
159 iterator.remove();
160 }
161 }
162 result.elements.add(current.reduce(aggregation));
163 }
164 return result;
165 }
166
167 @Override
168 public ImmutableCollection<T> filter(final Predicate<T> predicate) {
169 final ImmutableList<T> result = new ImmutableList<>();
170 final Iterator<T> iterator = this.elements.iterator();
171 while (iterator.hasNext()) {
172 final T current = iterator.next();
173 if (predicate.p(current)) {
174 result.elements.add(current);
175 }
176 }
177 return result;
178 }
179
180 @Override
181 public T find(final Predicate<T> predicate) {
182 final ImmutableCollection<T> preResult = this.filter(predicate);
183 if (preResult.isEmpty()) {
184 return null;
185 }
186 return preResult.front();
187 }
188
189 @Override
190 public String toString() {
191 return this.elements.toString();
192 }
193
194 @Override
195 public boolean equals(final Object obj) {
196 if (!(obj instanceof ImmutableList<?>)) {
197 return false;
198 }
199
200 final ImmutableList<?> other = (ImmutableList<?>) obj;
201
202 return this.elements.equals(other.elements);
203 }
204
205 @Override
206 public int hashCode() {
207 return this.elements.hashCode();
208 }
209
210 @Override
211 public boolean isEmpty() {
212 return this.elements.isEmpty();
213 }
214
215 }