private static <E> ImmutableSet<E> construct(int n, Object... elements) {
    switch (n) {
      case 0:
        return of();
      case 1:
        @SuppressWarnings("unchecked") // safe; elements contains only E's
        E elem = (E) elements[0];
        return of(elem);
      default:
        // continue below to handle the general case
    }
    int tableSize = chooseTableSize(n);
    Object[] table = new Object[tableSize];
    int mask = tableSize - 1;
    int hashCode = 0;
    int uniques = 0;
    for (int i = 0; i < n; i++) {
      Object element = checkElementNotNull(elements[i], i);
      int hash = element.hashCode();
      for (int j = Hashing.smear(hash); ; j++) {
        int index = j & mask;
        Object value = table[index];
        if (value == null) {
          // Came to an empty slot. Put the element here.
          elements[uniques++] = element;
          table[index] = element;
          hashCode += hash;
          break;
        } else if (value.equals(element)) {
          break;
        }
      }
    }
    Arrays.fill(elements, uniques, n, null);
    if (uniques == 1) {
      // There is only one element or elements are all duplicates
      @SuppressWarnings("unchecked") // we are careful to only pass in E
      E element = (E) elements[0];
      return new SingletonImmutableSet<E>(element, hashCode);
    } else if (tableSize != chooseTableSize(uniques)) {
      // Resize the table when the array includes too many duplicates.
      // when this happens, we have already made a copy
      return construct(uniques, elements);
    } else {
      Object[] uniqueElements =
          (uniques < elements.length) ? ObjectArrays.arraysCopyOf(elements, uniques) : elements;
      return new RegularImmutableSet<E>(uniqueElements, hashCode, table, mask);
    }
  }
private static < E > ImmutableSet < E > construct ( int n , Object ... elements ) { switch ( n ) { case 0 : return of ( ) ; case 1 : @ SuppressWarnings ( "unchecked" ) E elem = ( E ) elements [ 0 ] ; return of ( elem ) ; default : } int tableSize = chooseTableSize ( n ) ; Object [ ] table = new Object [ tableSize ] ; int mask = tableSize - 1 ; int hashCode = 0 ; int uniques = 0 ; for ( int i = 0 ; i < n ; i ++ ) { Object element = checkElementNotNull ( elements [ i ] , i ) ; int hash = element . hashCode ( ) ; for ( int j = Hashing . smear ( hash ) ; ; j ++ ) { int index = j & mask ; Object value = table [ index ] ; if ( value == null ) { elements [ uniques ++ ] = element ; table [ index ] = element ; hashCode += hash ; break ; } else if ( value . equals ( element ) ) { break ; } } } Arrays . fill ( elements , uniques , n , null ) ; if ( uniques == 1 ) { @ SuppressWarnings ( "unchecked" ) E element = ( E ) elements [ 0 ] ; return new SingletonImmutableSet < E > ( element , hashCode ) ; } else if ( tableSize != chooseTableSize ( uniques ) ) { return construct ( uniques , elements ) ; } else { Object [ ] uniqueElements = ( uniques < elements . length ) ? ObjectArrays . arraysCopyOf ( elements , uniques ) : elements ; return new RegularImmutableSet < E > ( uniqueElements , hashCode , table , mask ) ; } }
Constructs an {@code ImmutableSet} from the first {@code n} elements of the specified array.
If {@code k} is the size of the returned {@code ImmutableSet}, then the unique elements of
{@code elements} will be in the first {@code k} positions, and {@code elements[i] == null} for
{@code k <= i < n}.

<p>This may modify {@code elements}.  Additionally, if {@code n == elements.length} and
{@code elements} contains no duplicates, {@code elements} may be used without copying in the
returned {@code ImmutableSet}, in which case it may no longer be modified.

<p>{@code elements} may contain only values of type {@code E}.

@throws NullPointerException if any of the first {@code n} elements of {@code elements} is
null