@Realtime @DefaultTextFormat(value=FastCollection.Format.class) public abstract class FastCollection<E> extends Object implements Collection<E>, Serializable
A closure-based collection supporting numerous views which can be chained.
atomic()
- Thread-safe view for which all reads are mutex-free
and collection updates (including addAll
, removeIf
} are atomic.shared()
- Thread-safe view using allowing concurrent reads based
on mutex (
readers-writer locks).parallel()
- A view allowing parallel processing including updates
.sequential()
- View disallowing parallel processing.unmodifiable()
- View which does not allow any modification.filtered(filter)
- View exposing only the elements matching the specified filter.mapped(function)
- View exposing elements through the specified mapping function.sorted(comparator)
- View exposing elements sorted according to their natural order
of using a specified comparator.reversed()
- View exposing elements in the reverse iterative order.distinct()
- View exposing each element only once. Unmodifiable collections are not always immutable. An immutable
.
reference (or const reference) can only be obtained
when the originator
guarantees that the collection source will not be modified even by himself
(the value of the immutable reference being an unmodifiable
collection).
Immutable<List<String>> winners = new FastTable<String>().addAll("John Deuff", "Otto Graf", "Sim Kamil").toImmutable(); // Immutability is guaranteed, no reference left on the collection source.
Atomic collections use Copy-On-Write
optimizations in order to provide mutex-free read access. Only writes operations are mutually
exclusive. Collections can be optimized to not require the full copy during write operations
(e.g. immutable parts don't need to be copied). Still, when multiple updates are performed,
it is beneficial to group them into one single update
operation.
FastTable<String> tokens = ... ... // Replace null with "" in tokens. If tokens is atomic the update is atomic. // If tokens is parallel, the update is also performed concurrently ! tokens.update(new Consumer<List<String>>() { public void accept(List<String> view) { for (int i=0, n = view.size(); i < n; i++) if (view.get(i) == null) view.set(i, ""); } } });
The same code using closure (Java 8).
tokens.update((List<String> view) -> { for (int i = 0, n = view.size(); i < n; i++) { if (view.get(i) == null) view.set(i, ""); } });
Views are similar to Java 8 streams except that views are themselves collections (virtual collections) and actions on a view can impact the original collection. Collection views are nothing "new" since they already existed in the original java.util collection classes (e.g. List.subList(...), Map.keySet(), Map.values()). Javolution extends to this concept and allows views to be chained which addresses the concern of class proliferation.
FastTable<String> names = new FastTable<String>().addAll("Oscar Thon", "Eva Poret", "Paul Auchon"); boolean found = names.comparator(Equalities.LEXICAL_CASE_INSENSITIVE).contains("LUC SURIEUX"); names.subTable(0, n).clear(); // Removes the n first names (see java.util.List.subList). names.distinct().add("Guy Liguili"); // Adds "Guy Liguili" only if not already present. names.filtered(isLong).clear(); // Removes all the persons with long names. names.filtered(isLong).parallel().clear(); // Same as above but performed concurrently ! ... Predicate<CharSequence> isLong = new Predicate<CharSequence>() { public boolean test(CharSequence csq) { return csq.length() > 16; } });
Views can of course be used to perform "stream" oriented filter-map-reduce operations with the same benefits: Parallelism support, excellent memory characteristics (no caching and cost nothing to create), etc.
String anyLongName = names.filtered(isLong).any(String.class); // Returns any long name. int nbrChars = names.mapped(toLength).reduce(Reducers.sum()); // Returns the total number of characters. int maxLength = names.mapped(toLength).parallel().max(); // Finds the longest name in parallel. ... Function<CharSequence, Integer> toLength = new Function<CharSequence, Integer>() { public Integer apply(CharSequence csq) { return csq.length(); } }); // JDK Class.getEnclosingMethod using Javolution's views and Java 8 (to be compared with the current 20 lines implementation !). Method matching = new FastTable<Method>().addAll(enclosingInfo.getEnclosingClass().getDeclaredMethods()) .filtered(m -> Equalities.STANDARD.areEqual(m.getName(), enclosingInfo.getName()) .filtered(m -> Equalities.ARRAY.areEqual(m.getParameterTypes(), parameterClasses)) .filtered(m -> Equalities.STANDARD.areEqual(m.getReturnType(), returnType)) .any(Method.class); if (matching == null) throw new InternalError("Enclosing method not found"); return matching;
If a collection (or a map) is shared, derived views are also thread-safe.
Similarly, if a collection is parallel
, closure-based iterations
on derived views are performed concurrently.
FastMap<String, Runnable> tasks = ... ... tasks.values().parallel().forEach(new Consumer<Runnable>() { // Executes task concurrently. public void accept(Runnable task) { task.run(); } });
With Java 8, closures are greatly simplified using lambda expressions.
tasks.values().parallel().forEach(task -> task.run()); // Same as above. names.sorted().reversed().forEach(str -> System.out.println(str)); // Prints names in reverse alphabetical order.
Modifier and Type | Class and Description |
---|---|
static class |
FastCollection.Format
Default text format for fast collections (parsing not supported).
|
Modifier | Constructor and Description |
---|---|
protected |
FastCollection()
Default constructor.
|
Modifier and Type | Method and Description |
---|---|
boolean |
add(E element)
Adds the specified element to this collection
|
boolean |
addAll(Collection<? extends E> that)
Adds all the specified elements to this collection.
|
FastCollection<E> |
addAll(E... elements)
Returns this collection with the specified element added.
|
FastCollection<E> |
addAll(FastCollection<? extends E> that)
Returns this collection with the specified collection's elements added
in sequence.
|
<T extends E> |
any(Class<T> type)
Returns any non-null element of the specified type (convenience method).
|
FastCollection<E> |
atomic()
Returns an atomic view over this collection.
|
void |
clear()
Removes all elements from this collection.
|
Equality<? super E> |
comparator()
Returns the comparator uses by this collection for equality and/or
ordering if this collection is sorted.
|
boolean |
contains(Object searched)
Indicates if this collection contains the specified element.
|
boolean |
containsAll(Collection<?> that)
Indicates if this collection contains all the specified elements.
|
FastCollection<E> |
distinct()
Returns a view exposing only distinct elements (it does not iterate twice
over the
same elements). |
boolean |
equals(Object obj)
Compares the specified object with this collection for equality.
|
FastCollection<E> |
filtered(Predicate<? super E> filter)
Returns a view exposing only the elements matching the specified
filter.
|
void |
forEach(Consumer<? super E> consumer)
Iterates over all this collection elements applying the specified
consumer (convenience method).
|
int |
hashCode()
Returns the hash code of this collection.
|
boolean |
isEmpty()
Indicates if this collection is empty.
|
Iterator<E> |
iterator()
Returns an iterator over this collection elements.
|
<R> FastCollection<R> |
mapped(Function<? super E,? extends R> function)
Returns a view exposing elements through the specified mapping function.
|
E |
max()
Returns the largest element of this collection using this
collection
comparator (convenience method). |
E |
min()
Returns the smallest element of this collection using this
collection
comparator (convenience method). |
FastCollection<E> |
parallel()
Returns a parallel collection.
|
void |
perform(Consumer<? extends Collection<E>> action)
Executes the specified read-only action on this collection.
|
E |
reduce(Reducer<E> reducer)
Performs a reduction of the elements of this collection using the
specified reducer.
|
boolean |
remove(Object searched)
Removes the specified element from this collection.
|
boolean |
removeAll(Collection<?> that)
Removes all the specified element from this collection.
|
boolean |
removeIf(Predicate<? super E> filter)
Removes from this collection all the elements matching the specified
functional predicate (convenience method).
|
boolean |
retainAll(Collection<?> that)
Removes all the elements except those in the specified collection.
|
FastCollection<E> |
reversed()
Returns a view exposing elements in reverse iterative order.
|
FastCollection<E> |
sequential()
Returns a sequential view of this collection.
|
protected abstract CollectionService<E> |
service()
Returns the service implementation of this collection (for sub-classes).
|
protected static <E> CollectionService<E> |
serviceOf(FastCollection<E> collection)
Returns the service implementation of any fast collection
(for sub-classes).
|
FastCollection<E> |
shared()
Returns a thread-safe view over this collection.
|
int |
size()
Returns the size of this collection.
|
FastCollection<E> |
sorted()
Returns a view exposing elements sorted according to the
collection
order . |
FastCollection<E> |
sorted(Comparator<? super E> cmp)
Returns a view exposing elements sorted according to the specified
comparator.
|
Object[] |
toArray()
Returns an array holding this collection elements.
|
<T> T[] |
toArray(T[] array)
Returns the specified array holding this collection elements if
enough capacity.
|
<T extends Collection<E>> |
toImmutable()
Returns an immutable reference over this collection.
|
String |
toString()
Returns the string representation of this collection using its
default
format . |
FastCollection<E> |
unmodifiable()
Returns an unmodifiable view over this collection.
|
void |
update(Consumer<? extends Collection<E>> action)
Executes the specified update action on this collection.
|
@Parallelizable(mutexFree=true, comment="Except for write operations, all read operations are mutex-free.") public FastCollection<E> atomic()
ConcurrentModificationException
possible).@Parallelizable(mutexFree=false, comment="Use multiple-readers/single-writer lock.") public FastCollection<E> shared()
ConcurrentModificationException
possible).public FastCollection<E> parallel()
ConcurrentContext
.
The number of parallel views is derived from the context
concurrency
(number of parallel views = concurrency + 1
).
Parallel views do not require this collection to be thread-safe
(internal synchronization).public FastCollection<E> sequential()
public FastCollection<E> unmodifiable()
UnsupportedOperationException
being raised.public FastCollection<E> filtered(Predicate<? super E> filter)
public <R> FastCollection<R> mapped(Function<? super E,? extends R> function)
public FastCollection<E> sorted()
order
.public FastCollection<E> sorted(Comparator<? super E> cmp)
public FastCollection<E> reversed()
public FastCollection<E> distinct()
same
elements). Adding elements already
in the collection through this view has no effect. If this collection is
initially empty, using a distinct view to add new elements ensures that
this collection has no duplicate.@Realtime(limit=LINEAR) public void perform(Consumer<? extends Collection<E>> action)
parallel
.action
- the read-only action.UnsupportedOperationException
- if the action tries to update
this collection and this collection is thread-safe.ClassCastException
- if the action type is not compatible with
this collection (e.g. action on set and this is a list).update(Consumer)
@Realtime(limit=LINEAR) public void update(Consumer<? extends Collection<E>> action)
parallel
.
For atomic
collections the update is atomic
(either concurrent readers see the full result of the action or
nothing).action
- the update action.ClassCastException
- if the action type is not compatible with
this collection (e.g. action on set and this is a list).perform(Consumer)
@Realtime(limit=LINEAR) public void forEach(Consumer<? super E> consumer)
parallel
.consumer
- the functional consumer applied to the collection elements.@Realtime(limit=LINEAR) public boolean removeIf(Predicate<? super E> filter)
parallel
and
atomically if this collection is atomic
.filter
- a predicate returning true
for elements to be removed.true
if at least one element has been removed;
false
otherwise.@Realtime(limit=LINEAR) public E reduce(Reducer<E> reducer)
Reducers.any(java.lang.Class<? extends E>)
,
Reducers.and()
and Reducers.or()
may stop iterating
early. Reduction is performed concurrently if this collection is
parallel
.reducer
- the collection reducer.@Realtime(limit=LINEAR, comment="May have to search the whole collection (e.g. distinct view).") public boolean add(E element)
add
in interface Collection<E>
@Realtime(limit=LINEAR, comment="May actually iterates the whole collection (e.g. filtered view).") public boolean isEmpty()
isEmpty
in interface Collection<E>
@Realtime(limit=LINEAR, comment="Potentially counts the elements.") public int size()
size
in interface Collection<E>
@Realtime(limit=LINEAR, comment="Potentially removes elements one at a time.") public void clear()
clear
in interface Collection<E>
@Realtime(limit=LINEAR, comment="Potentially searches the whole collection.") public boolean contains(Object searched)
contains
in interface Collection<E>
@Realtime(limit=LINEAR, comment="Potentially searches the whole collection.") public boolean remove(Object searched)
remove
in interface Collection<E>
@Realtime(limit=N_SQUARE, comment="Construction of the iterator may require sorting the elements (e.g. sorted view)") public Iterator<E> iterator()
@Realtime(limit=LINEAR) public boolean addAll(Collection<? extends E> that)
addAll
in interface Collection<E>
@Realtime(limit=N_SQUARE) public boolean containsAll(Collection<?> that)
containsAll
in interface Collection<E>
@Realtime(limit=N_SQUARE) public boolean removeAll(Collection<?> that)
removeAll
in interface Collection<E>
@Realtime(limit=N_SQUARE) public boolean retainAll(Collection<?> that)
retainAll
in interface Collection<E>
@Realtime(limit=LINEAR) public Object[] toArray()
toArray
in interface Collection<E>
@Realtime(limit=LINEAR) public <T> T[] toArray(T[] array)
toArray
in interface Collection<E>
@Realtime(limit=LINEAR) public <T extends E> T any(Class<T> type)
type
- the element type searched for.reduce(Reducers.any(type))
Reducers.any(java.lang.Class<? extends E>)
@Realtime(limit=LINEAR) public E min()
comparator
(convenience method).
Returns null
if this collection is empty.reduce(Reducers.min(comparator()))
Reducers.min(java.util.Comparator<? super E>)
@Realtime(limit=LINEAR) public E max()
comparator
(convenience method).
Returns null
if this collection is empty.reduce(Reducers.max(comparator()))
Reducers.max(java.util.Comparator<? super E>)
@Realtime(limit=LINEAR) public FastCollection<E> addAll(E... elements)
elements
- the elements to be added.this
@Realtime(limit=LINEAR) public FastCollection<E> addAll(FastCollection<? extends E> that)
@Realtime(limit=CONSTANT) public Equality<? super E> comparator()
@Realtime(limit=CONSTANT) public <T extends Collection<E>> Immutable<T> toImmutable()
unmodifiable
view of this collection.
The caller must guarantees that the original collection is never going
to be updated (e.g. there is no reference left of the original collection).@Realtime(limit=LINEAR) public boolean equals(Object obj)
Collection.equals(Object)
specification
if this collection comparator
is
Equalities.STANDARD
(default). Otherwise, only collections
using the same comparator can be considered equals.equals
in interface Collection<E>
equals
in class Object
obj
- the object to be compared for equality with this collectiontrue
if both collections are considered equals;
false
otherwise.@Realtime(limit=LINEAR) public int hashCode()
Collection.hashCode()
specification
if this collection comparator
is
Equalities.STANDARD
.hashCode
in interface Collection<E>
hashCode
in class Object
@Realtime(limit=LINEAR) public String toString()
format
.protected abstract CollectionService<E> service()
protected static <E> CollectionService<E> serviceOf(FastCollection<E> collection)
Copyright © 2005-2013 Javolution. All Rights Reserved.