Class IndexedSet<T>

  • Type Parameters:
    T - the type of object
    All Implemented Interfaces:
    java.lang.Iterable<T>, java.util.Collection<T>, java.util.Set<T>

    @ThreadSafe
    public class IndexedSet<T>
    extends java.util.AbstractSet<T>
    A set of objects that are indexed and thus can be queried by specific fields of the object. Different IndexedSet instances may specify different fields to index. The field type must be comparable. The field value must not be changed after an object is added to the set, otherwise, behavior for all operations is not specified. If concurrent adds or removes for objects which are equivalent, but not the same exact object, the behavior is undefined. Therefore, do not add or remove "clones" objects in the IndexedSet.

    Example usage: We have a set of puppies:

       class Puppy {
         private final String mName;
         private final long mId;
    
         public Puppy(String name, long id) {
           mName = name;
           mId = id;
         }
    
         public String name() {
           return mName;
         }
    
         public long id() {
           return mId;
         }
       }
     
    We want to be able to retrieve the set of puppies via a puppy's id or name, one way is to have two maps like Map<String, Puppy> nameToPuppy and Map<Long, Puppy> idToPuppy, another way is to use a single instance of IndexedSet! First, define the fields to be indexed:
      IndexDefinition<Puppy> idIndex = new IndexDefinition<Puppy>(true) {
        @Override
        Object getFieldValue(Puppy o) {
          return o.id();
        }
      }
    
      IndexDefinition<Puppy> nameIndex = new IndexDefinition<Puppy>(true) {
        @Override
        Object getFieldValue(Puppy o) {
          return o.name();
        }
      }
     
    Then create an IndexedSet and add puppies:
      IndexedSet<Puppy> puppies = new IndexedSet<Puppy>(idIndex, nameIndex);
      puppies.add(new Puppy("sweet", 0));
      puppies.add(new Puppy("heart", 1));
     
    Then retrieve the puppy named sweet:
       Puppy sweet = puppies.getFirstByField(nameIndex, "sweet");
     
    and retrieve the puppy with id 1:
       Puppy heart = puppies.getFirstByField(idIndex, 1L);
     
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      boolean add​(T object)
      Adds an object o to the set if there is no other object o2 such that (o == null ? o2 == null : o.equals(o2)).
      void clear()
      Removes all the entries in this set.
      <V> boolean contains​(IndexDefinition<T,​V> indexDefinition, V value)
      Whether there is an object with the specified index field value in the set.
      <V> java.util.Set<T> getByField​(IndexDefinition<T,​V> indexDefinition, V value)
      Gets a subset of objects with the specified field value.
      <V> T getFirstByField​(IndexDefinition<T,​V> indexDefinition, V value)
      Gets the object from the set of objects with the specified field value.
      java.util.Iterator<T> iterator()
      Returns an iterator over the elements in this set.
      boolean remove​(java.lang.Object object)
      Removes an object from the set.
      <V> int removeByField​(IndexDefinition<T,​V> indexDefinition, V value)
      Removes the subset of objects with the specified index field value.
      int size()  
      • Methods inherited from class java.util.AbstractSet

        equals, hashCode, removeAll
      • Methods inherited from class java.util.AbstractCollection

        addAll, contains, containsAll, isEmpty, retainAll, toArray, toArray, toString
      • Methods inherited from class java.lang.Object

        clone, finalize, getClass, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface java.util.Collection

        parallelStream, removeIf, stream, toArray
      • Methods inherited from interface java.lang.Iterable

        forEach
      • Methods inherited from interface java.util.Set

        addAll, contains, containsAll, isEmpty, retainAll, spliterator, toArray, toArray
    • Constructor Detail

      • IndexedSet

        @SafeVarargs
        public IndexedSet​(IndexDefinition<T,​?> primaryIndexDefinition,
                          IndexDefinition<T,​?>... otherIndexDefinitions)
        Constructs a new IndexedSet instance with at least one field as the index.
        Parameters:
        primaryIndexDefinition - at least one field is needed to index the set of objects. This primaryIndexDefinition is used to initialize mPrimaryIndex and is recommended to be unique in consideration of performance.
        otherIndexDefinitions - other index definitions to index the set
    • Method Detail

      • clear

        public void clear()
        Removes all the entries in this set. This is an expensive operation, and concurrent adds are permitted.
        Specified by:
        clear in interface java.util.Collection<T>
        Specified by:
        clear in interface java.util.Set<T>
        Overrides:
        clear in class java.util.AbstractCollection<T>
      • add

        public boolean add​(T object)
        Adds an object o to the set if there is no other object o2 such that (o == null ? o2 == null : o.equals(o2)). If this set already contains the object, the call leaves the set unchanged.
        Specified by:
        add in interface java.util.Collection<T>
        Specified by:
        add in interface java.util.Set<T>
        Overrides:
        add in class java.util.AbstractCollection<T>
        Parameters:
        object - the object to add
        Returns:
        true if this set did not already contain the specified element
      • iterator

        public java.util.Iterator<T> iterator()
        Returns an iterator over the elements in this set. The elements are returned in no particular order. It is to implement Iterable so that users can foreach the IndexedSet directly. Note that the behavior of the iterator is unspecified if the underlying collection is modified while a thread is going through the iterator.
        Specified by:
        iterator in interface java.util.Collection<T>
        Specified by:
        iterator in interface java.lang.Iterable<T>
        Specified by:
        iterator in interface java.util.Set<T>
        Specified by:
        iterator in class java.util.AbstractCollection<T>
        Returns:
        an iterator over the elements in this IndexedSet
      • contains

        public <V> boolean contains​(IndexDefinition<T,​V> indexDefinition,
                                    V value)
        Whether there is an object with the specified index field value in the set.
        Type Parameters:
        V - the field type
        Parameters:
        indexDefinition - the field index definition
        value - the field value
        Returns:
        true if there is one such object, otherwise false
      • getByField

        public <V> java.util.Set<T> getByField​(IndexDefinition<T,​V> indexDefinition,
                                               V value)
        Gets a subset of objects with the specified field value. If there is no object with the specified field value, a newly created empty set is returned.
        Type Parameters:
        V - the field type
        Parameters:
        indexDefinition - the field index definition
        value - the field value to be satisfied
        Returns:
        the set of objects or an empty set if no such object exists
      • getFirstByField

        public <V> T getFirstByField​(IndexDefinition<T,​V> indexDefinition,
                                     V value)
        Gets the object from the set of objects with the specified field value.
        Type Parameters:
        V - the field type
        Parameters:
        indexDefinition - the field index definition
        value - the field value
        Returns:
        the object or null if there is no such object
      • remove

        public boolean remove​(java.lang.Object object)
        Removes an object from the set.
        Specified by:
        remove in interface java.util.Collection<T>
        Specified by:
        remove in interface java.util.Set<T>
        Overrides:
        remove in class java.util.AbstractCollection<T>
        Parameters:
        object - the object to remove
        Returns:
        true if the object is in the set and removed successfully, otherwise false
      • removeByField

        public <V> int removeByField​(IndexDefinition<T,​V> indexDefinition,
                                     V value)
        Removes the subset of objects with the specified index field value.
        Type Parameters:
        V - the field type
        Parameters:
        indexDefinition - the field index
        value - the field value
        Returns:
        the number of objects removed
      • size

        public int size()
        Specified by:
        size in interface java.util.Collection<T>
        Specified by:
        size in interface java.util.Set<T>
        Specified by:
        size in class java.util.AbstractCollection<T>
        Returns:
        the number of objects in this indexed set