From e28907d4bf4234cb988a5e76ebf7122c7c1ff6cb Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Sat, 19 Oct 2019 21:40:33 -0400 Subject: Added a generic ConditionalExistenceCollection --- .../math/ConditionalExistenceCollections.java | 87 +++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) (limited to 'src/org/unitConverter/math/ConditionalExistenceCollections.java') diff --git a/src/org/unitConverter/math/ConditionalExistenceCollections.java b/src/org/unitConverter/math/ConditionalExistenceCollections.java index c0a69f0..9522885 100644 --- a/src/org/unitConverter/math/ConditionalExistenceCollections.java +++ b/src/org/unitConverter/math/ConditionalExistenceCollections.java @@ -16,6 +16,7 @@ */ package org.unitConverter.math; +import java.util.AbstractCollection; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.Collection; @@ -48,8 +49,74 @@ import java.util.function.Predicate; * @author Adrien Hopkins * @since 2019-10-17 */ -// TODO add conditional existence Collections, Lists and Sorted/Navigable Sets/Maps +// TODO add conditional existence Lists and Sorted/Navigable Sets/Maps public final class ConditionalExistenceCollections { + /** + * Elements in this collection only exist if they meet a condition. + * + * @author Adrien Hopkins + * @since 2019-10-17 + * @param + * type of element in collection + */ + static final class ConditionalExistenceCollection extends AbstractCollection { + final Collection collection; + final Predicate existenceCondition; + + /** + * Creates the {@code ConditionalExistenceCollection}. + * + * @param collection + * @param existenceCondition + * @since 2019-10-17 + */ + private ConditionalExistenceCollection(final Collection collection, final Predicate existenceCondition) { + this.collection = collection; + this.existenceCondition = existenceCondition; + } + + @Override + public boolean add(final E e) { + return this.collection.add(e) && this.existenceCondition.test(e); + } + + @Override + public void clear() { + this.collection.clear(); + } + + @Override + public boolean contains(final Object o) { + if (!this.collection.contains(o)) + return false; + + // this collection can only contain instances of E + // since the object is in the collection, we know that it must be an instance of E + // therefore this cast will always work + @SuppressWarnings("unchecked") + final E e = (E) o; + + return this.existenceCondition.test(e); + } + + @Override + public Iterator iterator() { + return conditionalExistenceIterator(this.collection.iterator(), this.existenceCondition); + } + + @Override + public boolean remove(final Object o) { + // remove() must be first in the && statement, otherwise it may not execute + final boolean containedObject = this.contains(o); + return this.collection.remove(o) && containedObject; + } + + @Override + public int size() { + return (int) this.collection.stream().filter(this.existenceCondition).count(); + } + } + /** * Elements in this wrapper iterator only exist if they pass a condition. * @@ -258,6 +325,7 @@ public final class ConditionalExistenceCollections { @Override public boolean remove(final Object o) { + // remove() must be first in the && statement, otherwise it may not execute final boolean containedObject = this.contains(o); return this.set.remove(o) && containedObject; } @@ -268,6 +336,23 @@ public final class ConditionalExistenceCollections { } } + /** + * Elements in the returned wrapper collection are ignored if they don't pass a condition. + * + * @param + * type of elements in collection + * @param collection + * collection to wrap + * @param existenceCondition + * elements only exist if this returns true + * @return wrapper collection + * @since 2019-10-17 + */ + public static final Collection conditionalExistenceCollection(final Collection collection, + final Predicate existenceCondition) { + return new ConditionalExistenceCollection<>(collection, existenceCondition); + } + /** * Elements in the returned wrapper iterator are ignored if they don't pass a condition. * -- cgit v1.2.3