public class IntHashSet {
    private IntLinkedList[] buckets;
    private int size;

    private int capacity;

     private static final double LOAD_PERCENT = 0.7;

    public IntHashSet(){
        buckets = new IntLinkedList[16];
        capacity = 16;
    }

    private int hash(int value){
        return Math.floorMod(value, capacity);
    }
    private boolean loadReached(){
        return (double) size / capacity >= LOAD_PERCENT;
    }

    private void resize(){
        IntLinkedList[] oldBuckets = buckets;
        capacity *=2;
        buckets = new IntLinkedList[capacity];
        size = 0;
        for (IntLinkedList oldBucket : oldBuckets) {
            if (oldBucket == null) continue;
            for (int j = 0; j < oldBucket.getSize(); j++) {
                addWithoutResize(oldBucket.get(j));
            }
        }
    }


    public void add(int value){
        int index = hash(value);
        if (buckets[index] == null){
            buckets[index] = new IntLinkedList();
            buckets[index].add(value);
            size++;
            if (loadReached()) resize();
            return;
        }
        for (int i = 0; i < buckets[index].getSize(); i++){
            if (buckets[index].get(i) == value){
                return;
            }
        }
        buckets[index].add(value);
        size++;
        if (loadReached()) resize();
    }
    private void addWithoutResize(int value){
        int index = hash(value);
        if (buckets[index] == null){
            buckets[index] = new IntLinkedList();
            buckets[index].add(value);
            size++;
            return;
        }
        for (int i = 0; i < buckets[index].getSize(); i++){
            if (buckets[index].get(i) == value){
                return;
            }
        }
        buckets[index].add(value);
        size++;
    }
    public boolean contains(int value){
        int index = hash(value);
        if (buckets[index] == null){
            return false;
        }
        for (int i = 0; i < buckets[index].getSize(); i++){
            if (buckets[index].get(i) == value){
                return true;
            }
        }
        return false;
    }
}
