All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.javagimmicks.collections8.mapping.Mappings Maven / Gradle / Ivy

There is a newer version: 0.99-alpha1
Show newest version
package net.sf.javagimmicks.collections8.mapping;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import net.sf.javagimmicks.collections8.mapping.Mappings.Mapping;

/**
 * Represents a n:m relation between two sets of elements providing a backed
 * {@link Map} view of each "side" of the relation as well as many analytic and
 * modification operations.
 * 

* Example: Assume you have a set of persons - e.g. Alice, * Bob and Charles as well as a set of hobbies - e.g. * Astrology, Biking and Chess and you want to model any * associations between persons and hobbies, this class is just the right thing * for you: *

* The code below shows how to create an appropriate instance and fill it with * some mappings: * *

 * Mappings<Person, Hobby> m = DualMapMappings.<Person, Hobby> createTreeTreeInstance();
 * 
 * // Alice has hobbies Biking and Chess
 * m.put(Person.Alice, Hobby.Biking);
 * m.put(Person.Alice, Hobby.Chess);
 * 
 * // Bob has hobbies Astrology and Chess
 * m.put(Person.Bob, Hobby.Astrology);
 * m.put(Person.Bob, Hobby.Chess);
 * 
 * // Charles has hobbies Astrology and Biking
 * m.put(Person.Charles, Hobby.Astrology);
 * m.put(Person.Charles, Hobby.Biking);
 * 
* * Now you can get a "left view" (showing the hobbies for each person) and a * "right view" (showing the persons for each hobby) from the {@link Mappings} * object: * *
 * {@code
 * System.out.println(m.getLeftView());
 * // Prints {Alice=[Biking, Chess], Bob=[Astrology, Chess], Charles=[Astrology, Biking]}
 * 
 * System.out.println(m.getRightView());
 * // Prints {Astrology=[Bob, Charles], Biking=[Alice, Charles], Chess=[Alice, Bob]}
 * }
 * 
*

* For more things that you can do with {@link Mappings}, please consult the * method descriptions. *

* If additionally you want to assign a value for each mapping, * {@link ValueMappings} is the right choice for you * * @see ValueMappings * @param * the type of left keys of the {@link Mappings} * @param * the type of right keys of the {@link Mappings} */ public interface Mappings extends Iterable> { /** * Adds a new mapping (or association) between a given left key and right * key. * * @param left * the left key of the new mapping * @param right * the right key of the new mapping * @return if the {@link Mappings} was changed during this operation (i.e. * the mapping was new) */ boolean put(L left, R right); /** * Bulk-adds a bunch of left keys for a single given right key. * * @param right * the right key to add a bunch of left keys for * @param c * a {@link Collection} of left keys to add for the given right key * @return if the {@link Mappings} was changed during this operation */ default boolean putAllForRightKey(final R right, final Collection c) { boolean result = false; for (final L left : c) { result |= put(left, right); } return result; } /** * Bulk-adds a bunch of right keys for a single given left key. * * @param left * the left key to add a bunch of right keys for * @param c * a {@link Collection} of right keys to add for the given left key * @return if the {@link Mappings} was changed during this operation */ default boolean putAllForLeftKey(final L left, final Collection c) { boolean result = false; for (final R right : c) { result |= put(left, right); } return result; } /** * Removes a given mapping specified by left and right key from this * instance. * * @param left * the left key of the mapping to remove * @param right * the right key of the mapping to remove * @return if the {@link Mappings} was changed during this operation */ default boolean remove(final L left, final R right) { final Set mappedValuesLeft = getAllForLeftKey(left); return mappedValuesLeft != null ? mappedValuesLeft.remove(right) : false; } /** * Completely removes a given right key together with all it's mappings from * this instance. * * @param right * the right key to remove * @return the {@link Set} of left keys that were associated with the given * right key */ default Set removeRightKey(final R right) { return getRightView().remove(right); } /** * Completely removes a given left key together with all it's mappings from * this instance. * * @param left * the left key to remove * @return the {@link Set} of right keys that were associated with the given * left key */ default Set removeLeftKey(final L left) { return getLeftView().remove(left); } /** * Removes all mappings from this instance */ default void clear() { // Each view works bi-directional, so clearing one clear also the other getLeftView().clear(); } /** * Checks if a given mapping specified by left and right key is contained in * the current instance. * * @param left * the left key of the mapping to remove * @param right * the right key of the mapping to remove * @return if the specified mapping is contained in the current instance */ default boolean contains(final L left, final R right) { final Set rightSet = getAllForLeftKey(left); return rightSet != null && rightSet.contains(right); } /** * Check if any mappings are contained in this instance for a given left key. * * @param left * the left key to check for any existing mappings * @return if there is at least one mapping contained for the given left key */ default boolean containsLeftKey(final L left) { return getLeftView().containsKey(left); } /** * Check if any mappings are contained in this instance for a given right * key. * * @param right * the right key to check for any existing mappings * @return if there is at least one mapping contained for the given right key */ default boolean containsRightKey(final R right) { return getRightView().containsKey(right); } /** * Returns the number of mappings contained within the current instance. * * @return the number of mappings contained within the current instance */ default int size() { return getMappingSet().size(); } /** * Checks if the current instance contains no mappings. * * @return if the current instance contains no mappings */ boolean isEmpty(); /** * Returns all mappings contained within this instance as a {@link Set} of * {@link Mapping} instances. * * @return all mappings contained within this instance */ Set> getMappingSet(); /** * Return the "left view" of this instance - that is a {@link Map} that * contains the left mapping keys on the key side and a {@link Set} of the * associated right mapping keys for the left mapping key on the value side. * * @return the left view of this instance as {@link Map} */ Map> getLeftView(); /** * Return the "right view" of this instance - that is a {@link Map} that * contains the right mapping keys on the key side and a {@link Set} of the * associated left mapping keys for the right mapping key on the value side. * * @return the right view of this instance as {@link Map} */ Map> getRightView(); /** * Returns all left keys that are mapped to a given right key as a * {@link Set}. * * @param right * the right key to get all mapped left keys for * @return the {@link Set} of left keys mapped to the given right key */ default Set getAllForRightKey(final R right) { return getRightView().get(right); } /** * Returns all right keys that are mapped to a given left key as a * {@link Set}. * * @param left * the left key to get all mapped right keys for * @return the {@link Set} of right keys mapped to the given left key */ default Set getAllForLeftKey(final L left) { return getLeftView().get(left); } /** * Returns an inverted view of this instance (left and right keys are * exchanged). * * @return an inverted view of this instance */ Mappings invert(); /** * Returns an {@link Iterator} of all contained {@link Mapping}s. * * @see #getMappingSet() */ @Override default Iterator> iterator() { return getMappingSet().iterator(); } /** * Represents a single left-to-right mapping contained within a * {@link Mappings} object. * * @param * the type of left keys of the {@link Mapping} * @param * the type of right keys of the {@link Mapping} */ interface Mapping { /** * Returns the left key of the mapping. * * @return the left key of the mapping */ L getLeftKey(); /** * Returns the right key of the mapping. * * @return the right key of the mapping */ R getRightKey(); /** * Returns an inverted view of this instance (with exchanged left and * right key). * * @return an inverted view of this instance */ default Mapping invert() { return new Mapping() { @Override public Mapping invert() { return Mapping.this; } @Override public R getLeftKey() { return Mapping.this.getRightKey(); } @Override public L getRightKey() { return Mapping.this.getLeftKey(); } }; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy