Coverage Report - jaggregate.AbstractSet
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractSet
98%
52/53
100%
5/5
0
AbstractSet$1
100%
3/3
N/A
0
 
 1  
 /*
 2  
  Copyright 2004-2008 Paul R. Holser, Jr.  All rights reserved.
 3  
  Licensed under the Academic Free License version 3.0
 4  
  */
 5  
 
 6  
 package jaggregate;
 7  
 
 8  
 import java.io.IOException;
 9  
 import java.io.ObjectInputStream;
 10  
 import java.io.ObjectOutputStream;
 11  
 
 12  
 import static jaggregate.internal.Casting.*;
 13  
 
 14  
 /**
 15  
  * Represents an unordered, variable-sized collection whose <dfn>elements</dfn> can be
 16  
  * added or removed, but cannot be individually accessed by external <dfn>keys</dfn>.
 17  
  * <p/>
 18  
  * A set is similar to a {@linkplain Bag bag} but cannot contain duplicate elements.
 19  
  * Elements are duplicates if they are <dfn>equivalent</dfn>.
 20  
  *
 21  
  * @param <E> a restriction on the types of elements that may be included in the set
 22  
  *
 23  
  * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
 24  
  * @version $Id: AbstractSet.java,v 1.8 2008/10/03 19:01:23 pholser Exp $
 25  
  */
 26  0
 public abstract class AbstractSet<E> extends AbstractExtensibleCollection<E> {
 27  
     private transient AbstractDictionary<E, Object> storage;
 28  
 
 29  
     /**
 30  
      * Creates an empty set.
 31  
      */
 32  873
     protected AbstractSet() {
 33  873
         initialize();
 34  873
     }
 35  
 
 36  
     /**
 37  
      * Creates a set containing the elements in the given collection.
 38  
      *
 39  
      * @param elements elements to add to the new set
 40  
      * @throws NullPointerException if {@code elements} is {@code null}
 41  
      */
 42  
     protected AbstractSet( Collection<? extends E> elements ) {
 43  26
         this();
 44  26
         addAll( elements );
 45  24
     }
 46  
 
 47  
     /**
 48  
      * Creates a set containing the elements in the given array.
 49  
      *
 50  
      * @param elements elements to add to the new set
 51  
      * @throws NullPointerException if {@code elements} is {@code null}
 52  
      */
 53  
     protected AbstractSet( E... elements ) {
 54  360
         this();
 55  360
         addAll( elements );
 56  358
     }
 57  
 
 58  
     /**
 59  
      * Creates a set containing the elements in the given iterable object.
 60  
      *
 61  
      * @param elements elements to add to the new set
 62  
      * @throws NullPointerException if {@code elements} is {@code null}
 63  
      */
 64  
     protected AbstractSet( Iterable<? extends E> elements ) {
 65  4
         this();
 66  4
         addAll( elements );
 67  2
     }
 68  
 
 69  
     /**
 70  
      * {@inheritDoc}
 71  
      *
 72  
      * @return a set of results
 73  
      */
 74  
     @Override
 75  
     public <R> AbstractSet<R> collect(
 76  
         UnaryFunctor<? super E, ? extends R> transformer ) {
 77  
 
 78  6
         return (AbstractSet<R>) super.collect( transformer );
 79  
     }
 80  
 
 81  
     /**
 82  
      * {@inheritDoc}
 83  
      */
 84  
     public void forEachDo( UnaryFunctor<? super E, ?> operation ) {
 85  330
         storage.keysDo( operation );
 86  319
     }
 87  
 
 88  
     /**
 89  
      * {@inheritDoc}
 90  
      */
 91  
     @Override
 92  
     public boolean includes( E target ) {
 93  1337
         return storage.includesKey( target );
 94  
     }
 95  
 
 96  
     /**
 97  
      * {@inheritDoc}
 98  
      */
 99  
     @Override
 100  
     public int occurrencesOf( E target ) {
 101  21
         return includes( target ) ? 1 : 0;
 102  
     }
 103  
 
 104  
     /**
 105  
      * {@inheritDoc}
 106  
      */
 107  
     @Override
 108  
     public void rehash() {
 109  2
         storage.rehash();
 110  2
     }
 111  
 
 112  
     /**
 113  
      * {@inheritDoc}
 114  
      *
 115  
      * @return a set of rejects
 116  
      */
 117  
     @Override
 118  
     public AbstractSet<E> reject( UnaryCondition<? super E> discriminator ) {
 119  5
         return (AbstractSet<E>) super.reject( discriminator );
 120  
     }
 121  
 
 122  
     /**
 123  
      * {@inheritDoc}
 124  
      *
 125  
      * @return a set of selections
 126  
      */
 127  
     @Override
 128  
     public AbstractSet<E> select( UnaryCondition<? super E> discriminator ) {
 129  30
         return (AbstractSet<E>) super.select( discriminator );
 130  
     }
 131  
 
 132  
     /**
 133  
      * {@inheritDoc}
 134  
      */
 135  
     public int size() {
 136  161
         return storage.size();
 137  
     }
 138  
 
 139  
     /**
 140  
      * {@inheritDoc}
 141  
      */
 142  
     public void add( E newElement ) {
 143  2272
         storage.putAt( newElement, null );
 144  2272
     }
 145  
 
 146  
     /**
 147  
      * {@inheritDoc}
 148  
      */
 149  
     public boolean remove( E oldElement ) {
 150  309
         if ( includes( oldElement ) ) {
 151  244
             storage.removeKey( oldElement );
 152  244
             return true;
 153  
         }
 154  
 
 155  65
         return false;
 156  
     }
 157  
 
 158  
     /**
 159  
      * {@inheritDoc}
 160  
      * <p/>
 161  
      * An object is considered equivalent to this set if the object is assignable to
 162  
      * this set's class and has equivalent contents, as defined by the this set's notion
 163  
      * of equivalence.
 164  
      */
 165  
     @Override
 166  
     public boolean equals( Object that ) {
 167  722
         if ( this == that )
 168  168
             return true;
 169  
 
 170  554
         if ( !getImplementationClass().isInstance( that ) )
 171  8
             return false;
 172  
 
 173  546
         AbstractSet<?> other = (AbstractSet<?>) that;
 174  546
         return storage.equals( other.storage );
 175  
     }
 176  
 
 177  
     /**
 178  
      * Subclasses implement this method to answer the root of its true runtime class,
 179  
      * for purposes of determining {@linkplain #equals(Object) equivalence}.
 180  
      *
 181  
      * @return this set's implementation class
 182  
      */
 183  
     protected abstract Class<? extends AbstractSet> getImplementationClass();
 184  
 
 185  
     /**
 186  
      * {@inheritDoc}
 187  
      */
 188  
     @Override
 189  
     public int hashCode() {
 190  180
         return storage.hashCode();
 191  
     }
 192  
 
 193  
     /**
 194  
      * {@inheritDoc}
 195  
      */
 196  
     @Override
 197  
     public String toString() {
 198  10
         final StringBuilder buffer = new StringBuilder( "[" );
 199  
 
 200  10
         if ( !isEmpty() ) {
 201  8
             storage.keysDo( new UnaryFunctor<E, Void>() {
 202  20
                 public Void evaluate( E argument ) {
 203  12
                     buffer.append( asString( argument ) ).append( ',' );
 204  12
                     return null;
 205  
                 }
 206  
             } );
 207  
 
 208  8
             buffer.deleteCharAt( buffer.length() - 1 );
 209  
         }
 210  
 
 211  10
         buffer.append( ']' );
 212  
 
 213  10
         return buffer.toString();
 214  
     }
 215  
 
 216  
     /**
 217  
      * Answers a new, empty storage for the set.
 218  
      *
 219  
      * @return a new empty dictionary
 220  
      */
 221  
     protected abstract AbstractDictionary<E, Object> newEmptyStorage();
 222  
 
 223  
     /**
 224  
      * Tells how the given element will show up in this set's string representation.
 225  
      *
 226  
      * @param anElement an element of this collection
 227  
      * @return a string representation of {@code anElement} to be used in this set's
 228  
      * string representation
 229  
      */
 230  
     protected abstract String asString( E anElement );
 231  
 
 232  
     /**
 233  
      * Serialization helper method.
 234  
      *
 235  
      * @param output stream to write object state to
 236  
      * @throws IOException if an I/O problem occurs during serialization
 237  
      */
 238  
     protected final void serializeTo( ObjectOutputStream output ) throws IOException {
 239  2
         output.defaultWriteObject();
 240  2
         output.writeObject( storage );
 241  2
     }
 242  
 
 243  
     /**
 244  
      * De-serialization helper method.
 245  
      *
 246  
      * @param input stream to read object state from
 247  
      * @throws IOException if an I/O problem occurs during de-serialization
 248  
      * @throws ClassNotFoundException if a class that is necessary for de-serialization
 249  
      * cannot be found
 250  
      */
 251  
     protected final void deserializeFrom( ObjectInputStream input )
 252  
         throws IOException, ClassNotFoundException {
 253  
 
 254  2
         input.defaultReadObject();
 255  
 
 256  2
         AbstractDictionary<E, Object> backingStore = cast( input.readObject() );
 257  2
         initialize( backingStore );
 258  2
     }
 259  
 
 260  
     private void initialize() {
 261  873
         initialize( newEmptyStorage() );
 262  873
     }
 263  
 
 264  
     private void initialize( AbstractDictionary<E, Object> backingStore ) {
 265  875
         storage = backingStore;
 266  875
     }
 267  
 }