summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
blob: 5327dbe00bb7debb094727be7525e675bde3f16d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
package bjc.utils.funcdata;

import java.util.Comparator;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import bjc.utils.data.IPair;

/**
 * A wrapper over another list that provides eager functional operations
 * over it. Differs from a stream in every way except for the fact that
 * they both provide functional operations.
 * 
 * NOTE: The indications of complexity for methods assume that the backing
 * list has performance on the order of an array
 * 
 * @author ben
 *
 * @param <ContainedType>
 *            The type in this list
 */
public interface IFunctionalList<ContainedType> {

	/**
	 * Add an item to this list
	 * 
	 * Takes O(1) time.
	 * 
	 * @param item
	 *            The item to add to this list.
	 * @return Whether the item was added to the list succesfully.
	 */
	boolean add(ContainedType item);

	/**
	 * Check if all of the elements of this list match the specified
	 * predicate.
	 * 
	 * Takes O(f * p(n)) time on average, where f is defined as the average
	 * number of elements in a list until the predicate returns false, and
	 * p is the average running time of the predicate
	 * 
	 * @param matchPredicate
	 *            The predicate to use for checking.
	 * @return Whether all of the elements of the list match the specified
	 *         predicate.
	 */
	boolean allMatch(Predicate<ContainedType> matchPredicate);

	/**
	 * Check if any of the elements in this list match the specified list.
	 * 
	 * Takes O(f * p(n)) time on average, where f is defined as the average
	 * number of elements in a list until the predicate returns true, and p
	 * is the average running time of the predicate
	 * 
	 * @param matchPredicate
	 *            The predicate to use for checking.
	 * @return Whether any element in the list matches the provided
	 *         predicate.
	 */
	boolean anyMatch(Predicate<ContainedType> matchPredicate);

	/**
	 * Combine this list with another one into a new list and merge the
	 * results. Works sort of like a combined zip/map over resulting pairs.
	 * Does not change the underlying list.
	 * 
	 * NOTE: The returned list will have the length of the shorter of this
	 * list and the combined one.
	 * 
	 * Takes O(q * c(q)), where q is defined as the length of the shorter
	 * of this list and the provided one, and c is the running time of the
	 * combiner.
	 * 
	 * @param <OtherType>
	 *            The type of the second list
	 * @param <CombinedType>
	 *            The type of the combined list
	 * 
	 * @param rightList
	 *            The list to combine with
	 * @param itemCombiner
	 *            The function to use for combining element pairs.
	 * @return A new list containing the merged pairs of lists.
	 */
	<OtherType, CombinedType> IFunctionalList<CombinedType> combineWith(
			IFunctionalList<OtherType> rightList,
			BiFunction<ContainedType, OtherType, CombinedType> itemCombiner);

	/**
	 * Check if the list contains the specified item
	 * 
	 * Takes O(n) time, assuming object compare in constant time.
	 * 
	 * @param item
	 *            The item to see if it is contained
	 * @return Whether or not the specified item is in the list
	 */
	boolean contains(ContainedType item);

	/**
	 * Get the first element in the list
	 * 
	 * Takes O(1) time
	 * 
	 * @return The first element in this list.
	 */
	ContainedType first();

	/**
	 * Apply a function to each member of the list, then flatten the
	 * results. Does not change the underlying list.
	 * 
	 * Takes O(n * m) time, where m is the average number of elements in
	 * the returned list.
	 * 
	 * @param <MappedType>
	 *            The type of the flattened list
	 * 
	 * @param elementExpander
	 *            The function to apply to each member of the list.
	 * @return A new list containing the flattened results of applying the
	 *         provided function.
	 */
	<MappedType> IFunctionalList<MappedType> flatMap(
			Function<ContainedType, IFunctionalList<MappedType>> elementExpander);

	/**
	 * Apply a given action for each member of the list
	 * 
	 * Takes O(n * f(n)) time, where n is the length of the list, and f is
	 * the running time of the action.
	 * 
	 * @param action
	 *            The action to apply to each member of the list.
	 */
	void forEach(Consumer<ContainedType> action);

	/**
	 * Apply a given function to each element in the list and its index.
	 * 
	 * Takes O(n * f(n)) time, where n is the length of the list, and f is
	 * the running time of the action.
	 * 
	 * @param indexedAction
	 *            The function to apply to each element in the list and its
	 *            index.
	 */
	void forEachIndexed(BiConsumer<Integer, ContainedType> indexedAction);

	/**
	 * Retrieve a value in the list by its index.
	 * 
	 * Takes O(1) time.
	 * 
	 * @param index
	 *            The index to retrieve a value from.
	 * @return The value at the specified index in the list.
	 */
	ContainedType getByIndex(int index);

	/**
	 * Retrieve a list containing all elements matching a predicate
	 * 
	 * Takes O(n) time, where n is the number of elements in the list
	 * 
	 * @param matchPredicate
	 *            The predicate to match by
	 * @return A list containing all elements that match the predicate
	 */
	IFunctionalList<ContainedType> getMatching(
			Predicate<ContainedType> matchPredicate);

	/**
	 * Retrieve the size of the wrapped list
	 * 
	 * @return The size of the wrapped list
	 */
	int getSize();

	/**
	 * Check if this list is empty.
	 * 
	 * @return Whether or not this list is empty.
	 */
	boolean isEmpty();

	/**
	 * Create a new list by applying the given function to each element in
	 * the list. Does not change the underlying list.
	 * 
	 * @param <MappedType>
	 *            The type of the transformed list
	 * 
	 * @param elementTransformer
	 *            The function to apply to each element in the list
	 * @return A new list containing the mapped elements of this list.
	 */
	<MappedType> IFunctionalList<MappedType> map(
			Function<ContainedType, MappedType> elementTransformer);

	/**
	 * Zip two lists into a list of pairs
	 * 
	 * @param <OtherType>
	 *            The type of the second list
	 * 
	 * @param rightList
	 *            The list to use as the left side of the pair
	 * @return A list containing pairs of this element and the specified
	 *         list
	 */
	<OtherType> IFunctionalList<IPair<ContainedType, OtherType>> pairWith(
			IFunctionalList<OtherType> rightList);

	/**
	 * Partition this list into a list of sublists
	 * 
	 * @param numberPerPartition
	 *            The size of elements to put into each one of the sublists
	 * @return A list partitioned into partitions of size nPerPart
	 */
	IFunctionalList<IFunctionalList<ContainedType>> partition(
			int numberPerPartition);

	/**
	 * Prepend an item to the list
	 * 
	 * @param item
	 *            The item to prepend to the list
	 */
	void prepend(ContainedType item);

	/**
	 * Select a random item from this list, using the provided random
	 * number generator.
	 * 
	 * @param rnd
	 *            The random number generator to use.
	 * @return A random element from this list.
	 */
	ContainedType randItem(Function<Integer, Integer> rnd);

	/**
	 * Select a random item from the list, using a default random number
	 * generator
	 * 
	 * @return A random item from the list
	 */
	default ContainedType randItem() {
		return randItem((num) -> (int) (Math.random() * num));
	}

	/**
	 * Reduce this list to a single value, using a accumulative approach.
	 * 
	 * @param <StateType>
	 *            The in-between type of the values
	 * @param <ReducedType>
	 *            The final value type
	 * 
	 * @param initialValue
	 *            The initial value of the accumulative state.
	 * @param stateAccumulator
	 *            The function to use to combine a list element with the
	 *            accumulative state.
	 * @param resultTransformer
	 *            The function to use to convert the accumulative state
	 *            into a final result.
	 * @return A single value condensed from this list and transformed into
	 *         its final state.
	 */
	<StateType, ReducedType> ReducedType reduceAux(StateType initialValue,
			BiFunction<ContainedType, StateType, StateType> stateAccumulator,
			Function<StateType, ReducedType> resultTransformer);

	/**
	 * Remove all elements that match a given predicate
	 * 
	 * @param removePredicate
	 *            The predicate to use to determine elements to delete
	 * @return Whether there was anything that satisfied the predicate
	 */
	boolean removeIf(Predicate<ContainedType> removePredicate);

	/**
	 * Remove all parameters that match a given parameter
	 * 
	 * @param desiredElement
	 *            The object to remove all matching copies of
	 */
	void removeMatching(ContainedType desiredElement);

	/**
	 * Reverse the contents of this list in place
	 */
	void reverse();

	/**
	 * Perform a binary search for the specified key using the provided
	 * means of comparing elements. Since this IS a binary search, the list
	 * must have been sorted before hand.
	 * 
	 * @param searchKey
	 *            The key to search for.
	 * @param comparator
	 *            The way to compare elements for searching. Pass null to
	 *            use the natural ordering for E
	 * @return The element if it is in this list, or null if it is not.
	 */
	ContainedType search(ContainedType searchKey,
			Comparator<ContainedType> comparator);

	/**
	 * Sort the elements of this list using the provided way of comparing
	 * elements. Does change the underlying list.
	 * 
	 * @param comparator
	 *            The way to compare elements for sorting. Pass null to use
	 *            E's natural ordering
	 */
	void sort(Comparator<ContainedType> comparator);

	/**
	 * Get the tail of this list (the list without the first element
	 * 
	 * @return The list without the first element
	 */
	public IFunctionalList<ContainedType> tail();

	/**
	 * Convert this list into an array
	 * 
	 * @param arrType
	 *            The type of array to return
	 * @return The list, as an array
	 */
	ContainedType[] toArray(ContainedType[] arrType);

	/**
	 * Convert the list into a iterable
	 * 
	 * @return An iterable view onto the list
	 */
	Iterable<ContainedType> toIterable();
}