package ru.matevosyan;

import java.util.Arrays;

/**
 * FastSimpleSet class.
 * Created on 04.06.2017.
 * @author Matevosyan Vardan
 * @version 1.0
 */

public class FastSimpleSet<E> {

    private Object[] container;
    private static final int DEFAULT_ARRAY_SIZE = 10;
    private int index = 0;
    private int size = 0;

    /**
     * Constructor.
     * If arrays size was not passed to constructor, create an array with default size.
     */

    public FastSimpleSet() {
        this.container = new Object[DEFAULT_ARRAY_SIZE];
    }

    /**
     * Add method.
     * @param value that gonna be put in container.
     */

    public void add(E value) {
        checkSize(this.size + 1);

        if (!checkDuplicate(value)) {
            int hash = hash(value);
            this.container[this.container.length - 1 & hash] = value;
            size++;

        }
    }

    private int hash(E value) {
        int h = 0;
        return h = value.hashCode() ^ (h >>> 16);
    }

    /**
     * Check array size and rise it when an array length is equal or bigger that default size.
     * Or if it is the last index that going to be hold by passing value.
     * @param nextIndex is next index that going to be checked.
     */

    private void checkSize(int nextIndex) {
        if (this.container.length - 1 == nextIndex && this.container.length >= DEFAULT_ARRAY_SIZE) {
            int nexSize = (this.container.length * 3) / 2 + 1;
            this.container = Arrays.copyOf(this.container, nexSize);
        }
    }

    /**
     * Override method {@link DynamicSimpleSet#checkDuplicate(Object)} and use binary search.
     * @param value value that gonna be compare with element in an array.
     * @return true if container has duplicates.
     */


    public boolean checkDuplicate(E value) {

        int left = 0;
        int size = 0;

        for (Object o : this.container) {
            if (o != null) {
                size++;
            }
        }

        int right = size - 1;

        boolean theSame = false;

            while (left <= right) {
                int mid = left + ((right - left) / 2);
                int hashObject = 0;

                if (this.container[mid] != null) {
                    hashObject = this.container[mid].hashCode();
                }

                if (hashObject == value.hashCode()) {
                    theSame = true;
                } else if (hashObject < value.hashCode()) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
        return theSame;
    }

}

@@ -42,16 +42,44 @@
 Arrays;%0A
+import java.util.Iterator;%0A%0A
 %0A/**%0A * 
@@ -204,16 +204,39 @@
 leSet%3CE%3E
+ implements Iterable%3CE%3E
  %7B%0A%0A    
@@ -848,36 +848,8 @@
 ner%5B
-this.container.length - 1 & 
 hash
@@ -893,24 +893,120 @@
    %7D%0A    %7D%0A%0A
+    /**%0A     * Bucket index.%0A     * @param value input.%0A     * @return bucket index.%0A     */%0A%0A//
     private 
@@ -1017,32 +1017,34 @@
 hash(E value) %7B%0A
+//
         int h = 
@@ -1046,24 +1046,26 @@
  h = 0;%0A
+//
         
 return h
@@ -1056,23 +1056,16 @@
         
-return 
 h = valu
@@ -1080,20 +1080,212 @@
 de()
- %5E (h %3E%3E%3E 16
+;%0A//        h = h %5E (h %3E%3E%3E 16);%0A//        h = (this.container.length - 1) & h;%0A//        return  h;%0A//    %7D%0A    private int hash(E value) %7B%0A        return Math.abs(value.hashCode() %25 this.container.length
 );%0A 
@@ -1281,33 +1281,32 @@
 .length);%0A    %7D%0A
-%0A
     /**%0A     * C
@@ -1825,32 +1825,154 @@
        %7D%0A    %7D%0A%0A
+    /**%0A     * Get array size.%0A     * @return array size.%0A     */%0A%0A    public int getSize() %7B%0A        return size;%0A    %7D%0A%0A
     /**%0A     * O
@@ -3040,10 +3040,814 @@
 %0A    %7D%0A%0A
+    /**%0A     * Get value.%0A     * @param value that want to get.%0A     * @return value type of E.%0A     */%0A%0A    @SuppressWarnings(%22unchecked%22)%0A    public E get(E value) %7B%0A        int h = hash(value);%0A        return  (E) this.container%5Bh%5D;%0A     %7D%0A%0A    /**%0A     * Override iterator method from interface Iterable.%0A     * @return an instance of Iterator type.%0A     */%0A%0A    @Override%0A    public Iterator%3CE%3E iterator() %7B%0A%0A        return new Iterator%3CE%3E() %7B%0A%0A            int count = 0;%0A            @Override%0A            public boolean hasNext() %7B%0A                return count %3C container.length - (container.length - size);%0A            %7D%0A%0A            @Override%0A            @SuppressWarnings(%22unchecked%22)%0A            public E next() %7B%0A                return (E) container%5Bcount++%5D;%0A            %7D%0A        %7D;%0A    %7D%0A%0A
 %7D%0A

add getSize method