diff options
Diffstat (limited to 'src/org/unitConverter/math/ConditionalExistenceCollections.java')
| -rw-r--r-- | src/org/unitConverter/math/ConditionalExistenceCollections.java | 468 | 
1 files changed, 0 insertions, 468 deletions
| diff --git a/src/org/unitConverter/math/ConditionalExistenceCollections.java b/src/org/unitConverter/math/ConditionalExistenceCollections.java deleted file mode 100644 index ac1c0cf..0000000 --- a/src/org/unitConverter/math/ConditionalExistenceCollections.java +++ /dev/null @@ -1,468 +0,0 @@ -/** - * Copyright (C) 2019 Adrien Hopkins - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ -package org.unitConverter.math; - -import java.util.AbstractCollection; -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.function.Predicate; - -/** - * Elements in these wrapper collections only exist if they pass a condition. - * <p> - * All of the collections in this class are "views" of the provided collections. - * They are mutable if the provided collections are mutable, they allow null if - * the provided collections allow null, they will reflect changes in the - * provided collection, etc. - * <p> - * The modification operations will always run the corresponding operations, - * even if the conditional existence collection doesn't change. For example, if - * you have a set that ignores even numbers, add(2) will still add a 2 to the - * backing set (but the conditional existence set will say it doesn't exist). - * <p> - * The returned collections do <i>not</i> pass the hashCode and equals - * operations through to the backing collections, but rely on {@code Object}'s - * {@code equals} and {@code hashCode} methods. This is necessary to preserve - * the contracts of these operations in the case that the backing collections - * are sets or lists. - * <p> - * Other than that, <i>the only difference between the provided collections and - * the returned collections are that elements don't exist if they don't pass the - * provided condition</i>. - *  - *  - * @author Adrien Hopkins - * @since 2019-10-17 - */ -// 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 <E> type of element in collection -	 */ -	static final class ConditionalExistenceCollection<E> -			extends AbstractCollection<E> { -		final Collection<E> collection; -		final Predicate<E> existenceCondition; -		 -		/** -		 * Creates the {@code ConditionalExistenceCollection}. -		 *  -		 * @param collection -		 * @param existenceCondition -		 * @since 2019-10-17 -		 */ -		private ConditionalExistenceCollection(final Collection<E> collection, -				final Predicate<E> 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<E> 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(); -		} -		 -		@Override -		public Object[] toArray() { -			// ensure the toArray operation is supported -			this.collection.toArray(); -			 -			// if it works, do it for real -			return super.toArray(); -		} -		 -		@Override -		public <T> T[] toArray(T[] a) { -			// ensure the toArray operation is supported -			this.collection.toArray(); -			 -			// if it works, do it for real -			return super.toArray(a); -		} -	} -	 -	/** -	 * Elements in this wrapper iterator only exist if they pass a condition. -	 *  -	 * @author Adrien Hopkins -	 * @since 2019-10-17 -	 * @param <E> type of elements in iterator -	 */ -	static final class ConditionalExistenceIterator<E> implements Iterator<E> { -		final Iterator<E> iterator; -		final Predicate<E> existenceCondition; -		E nextElement; -		boolean hasNext; -		 -		/** -		 * Creates the {@code ConditionalExistenceIterator}. -		 *  -		 * @param iterator -		 * @param condition -		 * @since 2019-10-17 -		 */ -		private ConditionalExistenceIterator(final Iterator<E> iterator, -				final Predicate<E> condition) { -			this.iterator = iterator; -			this.existenceCondition = condition; -			this.getAndSetNextElement(); -		} -		 -		/** -		 * Gets the next element, and sets nextElement and hasNext accordingly. -		 *  -		 * @since 2019-10-17 -		 */ -		private void getAndSetNextElement() { -			do { -				if (!this.iterator.hasNext()) { -					this.nextElement = null; -					this.hasNext = false; -					return; -				} -				this.nextElement = this.iterator.next(); -			} while (!this.existenceCondition.test(this.nextElement)); -			this.hasNext = true; -		} -		 -		@Override -		public boolean hasNext() { -			return this.hasNext; -		} -		 -		@Override -		public E next() { -			if (this.hasNext()) { -				final E next = this.nextElement; -				this.getAndSetNextElement(); -				return next; -			} else -				throw new NoSuchElementException(); -		} -		 -		@Override -		public void remove() { -			this.iterator.remove(); -		} -	} -	 -	/** -	 * Mappings in this map only exist if the entry passes some condition. -	 *  -	 * @author Adrien Hopkins -	 * @since 2019-10-17 -	 * @param <K> key type -	 * @param <V> value type -	 */ -	static final class ConditionalExistenceMap<K, V> extends AbstractMap<K, V> { -		Map<K, V> map; -		Predicate<Entry<K, V>> entryExistenceCondition; -		 -		/** -		 * Creates the {@code ConditionalExistenceMap}. -		 *  -		 * @param map -		 * @param entryExistenceCondition -		 * @since 2019-10-17 -		 */ -		private ConditionalExistenceMap(final Map<K, V> map, -				final Predicate<Entry<K, V>> entryExistenceCondition) { -			this.map = map; -			this.entryExistenceCondition = entryExistenceCondition; -		} -		 -		@Override -		public boolean containsKey(final Object key) { -			if (!this.map.containsKey(key)) -				return false; -				 -			// only instances of K have mappings in the backing map -			// since we know that key is a valid key, it must be an instance of K -			@SuppressWarnings("unchecked") -			final K keyAsK = (K) key; -			 -			// get and test entry -			final V value = this.map.get(key); -			final Entry<K, V> entry = new SimpleEntry<>(keyAsK, value); -			return this.entryExistenceCondition.test(entry); -		} -		 -		@Override -		public Set<Entry<K, V>> entrySet() { -			return conditionalExistenceSet(this.map.entrySet(), -					this.entryExistenceCondition); -		} -		 -		@Override -		public V get(final Object key) { -			return this.containsKey(key) ? this.map.get(key) : null; -		} -		 -		private final Entry<K, V> getEntry(K key) { -			return new Entry<K, V>() { -				@Override -				public K getKey() { -					return key; -				} -				 -				@Override -				public V getValue() { -					return ConditionalExistenceMap.this.map.get(key); -				} -				 -				@Override -				public V setValue(V value) { -					return ConditionalExistenceMap.this.map.put(key, value); -				} -			}; -		} -		 -		@Override -		public Set<K> keySet() { -			return conditionalExistenceSet(super.keySet(), -					k -> this.entryExistenceCondition.test(this.getEntry(k))); -		} -		 -		@Override -		public V put(final K key, final V value) { -			final V oldValue = this.map.put(key, value); -			 -			// get and test entry -			final Entry<K, V> entry = new SimpleEntry<>(key, oldValue); -			return this.entryExistenceCondition.test(entry) ? oldValue : null; -		} -		 -		@Override -		public V remove(final Object key) { -			final V oldValue = this.map.remove(key); -			return this.containsKey(key) ? oldValue : null; -		} -		 -		@Override -		public Collection<V> values() { -			// maybe change this to use ConditionalExistenceCollection -			return super.values(); -		} -	} -	 -	/** -	 * Elements in this set only exist if a certain condition is true. -	 *  -	 * @author Adrien Hopkins -	 * @since 2019-10-17 -	 * @param <E> type of element in set -	 */ -	static final class ConditionalExistenceSet<E> extends AbstractSet<E> { -		private final Set<E> set; -		private final Predicate<E> existenceCondition; -		 -		/** -		 * Creates the {@code ConditionalNonexistenceSet}. -		 *  -		 * @param set                set to use -		 * @param existenceCondition condition where element exists -		 * @since 2019-10-17 -		 */ -		private ConditionalExistenceSet(final Set<E> set, -				final Predicate<E> existenceCondition) { -			this.set = set; -			this.existenceCondition = existenceCondition; -		} -		 -		/** -		 * {@inheritDoc} -		 * <p> -		 * Note that this method returns {@code false} if {@code e} does not pass -		 * the existence condition. -		 */ -		@Override -		public boolean add(final E e) { -			return this.set.add(e) && this.existenceCondition.test(e); -		} -		 -		@Override -		public void clear() { -			this.set.clear(); -		} -		 -		@Override -		public boolean contains(final Object o) { -			if (!this.set.contains(o)) -				return false; -				 -			// this set can only contain instances of E -			// since the object is in the set, 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<E> iterator() { -			return conditionalExistenceIterator(this.set.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.set.remove(o) && containedObject; -		} -		 -		@Override -		public int size() { -			return (int) this.set.stream().filter(this.existenceCondition).count(); -		} -		 -		@Override -		public Object[] toArray() { -			// ensure the toArray operation is supported -			this.set.toArray(); -			 -			// if it works, do it for real -			return super.toArray(); -		} -		 -		@Override -		public <T> T[] toArray(T[] a) { -			// ensure the toArray operation is supported -			this.set.toArray(); -			 -			// if it works, do it for real -			return super.toArray(a); -		} -	} -	 -	/** -	 * Elements in the returned wrapper collection are ignored if they don't pass -	 * a condition. -	 *  -	 * @param <E>                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 <E> Collection<E> conditionalExistenceCollection( -			final Collection<E> collection, -			final Predicate<E> existenceCondition) { -		return new ConditionalExistenceCollection<>(collection, -				existenceCondition); -	} -	 -	/** -	 * Elements in the returned wrapper iterator are ignored if they don't pass a -	 * condition. -	 *  -	 * @param <E>                type of elements in iterator -	 * @param iterator           iterator to wrap -	 * @param existenceCondition elements only exist if this returns true -	 * @return wrapper iterator -	 * @since 2019-10-17 -	 */ -	public static final <E> Iterator<E> conditionalExistenceIterator( -			final Iterator<E> iterator, final Predicate<E> existenceCondition) { -		return new ConditionalExistenceIterator<>(iterator, existenceCondition); -	} -	 -	/** -	 * Mappings in the returned wrapper map are ignored if the corresponding -	 * entry doesn't pass a condition -	 *  -	 * @param <K>                     type of key in map -	 * @param <V>                     type of value in map -	 * @param map                     map to wrap -	 * @param entryExistenceCondition mappings only exist if this returns true -	 * @return wrapper map -	 * @since 2019-10-17 -	 */ -	public static final <K, V> Map<K, V> conditionalExistenceMap( -			final Map<K, V> map, -			final Predicate<Entry<K, V>> entryExistenceCondition) { -		return new ConditionalExistenceMap<>(map, entryExistenceCondition); -	} -	 -	/** -	 * Elements in the returned wrapper set are ignored if they don't pass a -	 * condition. -	 *  -	 * @param <E>                type of elements in set -	 * @param set                set to wrap -	 * @param existenceCondition elements only exist if this returns true -	 * @return wrapper set -	 * @since 2019-10-17 -	 */ -	public static final <E> Set<E> conditionalExistenceSet(final Set<E> set, -			final Predicate<E> existenceCondition) { -		return new ConditionalExistenceSet<>(set, existenceCondition); -	} -} | 
