Coverage Report - com.jcabi.immutable.ArraySet
 
Classes in this File Line Coverage Branch Coverage Complexity
ArraySet
44%
30/68
25%
6/24
2
 
 1  
 /**
 2  
  * Copyright (c) 2012-2014, jcabi.com
 3  
  * All rights reserved.
 4  
  *
 5  
  * Redistribution and use in source and binary forms, with or without
 6  
  * modification, are permitted provided that the following conditions
 7  
  * are met: 1) Redistributions of source code must retain the above
 8  
  * copyright notice, this list of conditions and the following
 9  
  * disclaimer. 2) Redistributions in binary form must reproduce the above
 10  
  * copyright notice, this list of conditions and the following
 11  
  * disclaimer in the documentation and/or other materials provided
 12  
  * with the distribution. 3) Neither the name of the jcabi.com nor
 13  
  * the names of its contributors may be used to endorse or promote
 14  
  * products derived from this software without specific prior written
 15  
  * permission.
 16  
  *
 17  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18  
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 19  
  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 20  
  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 21  
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 22  
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 23  
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 24  
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 25  
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 26  
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 27  
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 28  
  * OF THE POSSIBILITY OF SUCH DAMAGE.
 29  
  */
 30  
 package com.jcabi.immutable;
 31  
 
 32  
 import com.jcabi.aspects.Immutable;
 33  
 import com.jcabi.aspects.Loggable;
 34  
 import java.util.Arrays;
 35  
 import java.util.Collection;
 36  
 import java.util.Collections;
 37  
 import java.util.HashSet;
 38  
 import java.util.Iterator;
 39  
 import java.util.LinkedList;
 40  
 import java.util.Set;
 41  
 
 42  
 /**
 43  
  * Set on top of array.
 44  
  *
 45  
  * <p>This class is truly immutable. This means that it never changes
 46  
  * its encapsulated values and is annotated with {@code &#64;Immutable}
 47  
  * annotation.
 48  
  *
 49  
  * @param <T> Value key type
 50  
  * @author Yegor Bugayenko (yegor@tpc2.com)
 51  
  * @version $Id$
 52  
  * @since 0.1
 53  
  */
 54  
 @Immutable
 55  
 @Loggable(Loggable.DEBUG)
 56  
 @SuppressWarnings({ "unchecked", "PMD.TooManyMethods" })
 57  
 public final class ArraySet<T> implements Set<T> {
 58  
 
 59  
     /**
 60  
      * All vals.
 61  
      */
 62  
     @Immutable.Array
 63  
     private final transient T[] values;
 64  
 
 65  
     /**
 66  
      * Public ctor.
 67  
      */
 68  3
     public ArraySet() {
 69  3
         this.values = (T[]) new Object[0];
 70  3
     }
 71  
 
 72  
     /**
 73  
      * Public ctor.
 74  
      * @param set Original set
 75  
      * @since 0.12
 76  
      */
 77  13
     public ArraySet(final Iterable<T> set) {
 78  13
         if (set == null) {
 79  0
             throw new IllegalArgumentException(
 80  
                 "argument of ArraySet ctor can't be NULL"
 81  
             );
 82  
         }
 83  13
         if (set instanceof ArraySet) {
 84  0
             this.values = ((ArraySet<T>) set).values;
 85  13
         } else if (set instanceof Collection) {
 86  13
             final Set<T> hset = new HashSet<T>(Collection.class.cast(set));
 87  13
             this.values = hset.toArray((T[]) new Object[hset.size()]);
 88  13
         } else {
 89  0
             final Set<T> hset = new HashSet<T>(0);
 90  0
             for (final T item : set) {
 91  0
                 hset.add(item);
 92  0
             }
 93  0
             this.values = hset.toArray((T[]) new Object[hset.size()]);
 94  
         }
 95  13
     }
 96  
 
 97  
     /**
 98  
      * Make a new one with an extra entry.
 99  
      * @param value The value
 100  
      * @return New set
 101  
      */
 102  
     public ArraySet<T> with(final T value) {
 103  8
         if (value == null) {
 104  0
             throw new IllegalArgumentException(
 105  
                 "argument of ArraySet#with() can't be NULL"
 106  
             );
 107  
         }
 108  8
         final Collection<T> list = new HashSet<T>(this.size() + 1);
 109  8
         list.addAll(this);
 110  8
         list.remove(value);
 111  8
         list.add(value);
 112  8
         return new ArraySet<T>(list);
 113  
     }
 114  
 
 115  
     /**
 116  
      * Make a new one with some extra entries.
 117  
      * @param vals Values to add
 118  
      * @return New set
 119  
      */
 120  
     public ArraySet<T> with(final Collection<T> vals) {
 121  0
         if (vals == null) {
 122  0
             throw new IllegalArgumentException(
 123  
                 "arguments of ArraySet#with() can't be NULL"
 124  
             );
 125  
         }
 126  0
         final Collection<T> list = new HashSet<T>(this.size());
 127  0
         list.addAll(this);
 128  0
         list.removeAll(vals);
 129  0
         list.addAll(vals);
 130  0
         return new ArraySet<T>(list);
 131  
     }
 132  
 
 133  
     /**
 134  
      * Make a new one without an extra entry.
 135  
      * @param value The value
 136  
      * @return New set
 137  
      */
 138  
     public ArraySet<T> without(final T value) {
 139  3
         if (value == null) {
 140  0
             throw new IllegalArgumentException(
 141  
                 "argument of ArraySet#without() can't be NULL"
 142  
             );
 143  
         }
 144  3
         final Collection<T> list = new LinkedList<T>();
 145  3
         list.addAll(this);
 146  3
         list.remove(value);
 147  3
         return new ArraySet<T>(list);
 148  
     }
 149  
 
 150  
     @Override
 151  
     public int hashCode() {
 152  0
         return Arrays.hashCode(this.values);
 153  
     }
 154  
 
 155  
     @Override
 156  
     public boolean equals(final Object object) {
 157  
         final boolean equals;
 158  1
         if (object instanceof ArraySet) {
 159  1
             equals = Arrays.deepEquals(
 160  
                 this.values, ArraySet.class.cast(object).values
 161  
             );
 162  
         } else {
 163  0
             equals = false;
 164  
         }
 165  1
         return equals;
 166  
     }
 167  
 
 168  
     @Override
 169  
     public String toString() {
 170  0
         final StringBuilder text = new StringBuilder();
 171  0
         for (final T item : this.values) {
 172  0
             if (text.length() > 0) {
 173  0
                 text.append(", ");
 174  
             }
 175  0
             text.append(item);
 176  
         }
 177  0
         return text.toString();
 178  
     }
 179  
 
 180  
     @Override
 181  
     public int size() {
 182  9
         return this.values.length;
 183  
     }
 184  
 
 185  
     @Override
 186  
     public boolean isEmpty() {
 187  0
         return this.values.length == 0;
 188  
     }
 189  
 
 190  
     @Override
 191  
     public boolean contains(final Object key) {
 192  0
         return Arrays.asList(this.values).contains(key);
 193  
     }
 194  
 
 195  
     @Override
 196  
     public Iterator<T> iterator() {
 197  12
         return Collections.unmodifiableList(
 198  
             Arrays.asList(this.values)
 199  
         ).iterator();
 200  
     }
 201  
 
 202  
     @Override
 203  
     public Object[] toArray() {
 204  3
         final Object[] array = new Object[this.values.length];
 205  3
         System.arraycopy(this.values, 0, array, 0, this.values.length);
 206  3
         return array;
 207  
     }
 208  
 
 209  
     @Override
 210  
     public <T> T[] toArray(final T[] array) {
 211  
         T[] dest;
 212  0
         if (array.length == this.values.length) {
 213  0
             dest = array;
 214  
         } else {
 215  0
             dest = (T[]) new Object[this.values.length];
 216  
         }
 217  0
         System.arraycopy(this.values, 0, dest, 0, this.values.length);
 218  0
         return dest;
 219  
     }
 220  
 
 221  
     @Override
 222  
     public boolean add(final T element) {
 223  0
         throw new UnsupportedOperationException();
 224  
     }
 225  
 
 226  
     @Override
 227  
     public boolean remove(final Object obj) {
 228  0
         throw new UnsupportedOperationException();
 229  
     }
 230  
 
 231  
     @Override
 232  
     public boolean containsAll(final Collection<?> col) {
 233  0
         return Arrays.asList(this.values).containsAll(col);
 234  
     }
 235  
 
 236  
     @Override
 237  
     public boolean addAll(final Collection<? extends T> col) {
 238  0
         throw new UnsupportedOperationException();
 239  
     }
 240  
 
 241  
     @Override
 242  
     public boolean retainAll(final Collection<?> col) {
 243  0
         throw new UnsupportedOperationException();
 244  
     }
 245  
 
 246  
     @Override
 247  
     public boolean removeAll(final Collection<?> col) {
 248  0
         throw new UnsupportedOperationException();
 249  
     }
 250  
 
 251  
     @Override
 252  
     public void clear() {
 253  0
         throw new UnsupportedOperationException();
 254  
     }
 255  
 
 256  
 }