All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.marksman.collectionviews.ConcreteVectorBuilder Maven / Gradle / Ivy

There is a newer version: 1.2.3
Show newest version
package dev.marksman.collectionviews;

import com.jnape.palatable.lambda.adt.Maybe;
import dev.marksman.enhancediterables.FiniteIterable;
import dev.marksman.enhancediterables.NonEmptyFiniteIterable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;

final class ConcreteVectorBuilder implements NonEmptyVectorBuilder {
    private final Maybe initialCapacity;
    private final ArrayList underlying;
    private final int size;

    private ConcreteVectorBuilder(int size, Maybe initialCapacity, ArrayList underlying) {
        this.initialCapacity = initialCapacity;
        this.underlying = underlying;
        this.size = size;
    }

    @Override
    public NonEmptyVectorBuilder add(A element) {
        ArrayList nextUnderlying = getNextUnderlying();
        nextUnderlying.add(element);
        return concreteVectorBuilder(nextUnderlying.size(), initialCapacity, nextUnderlying);
    }

    @Override
    public NonEmptyVectorBuilder addAll(Collection elements) {
        Objects.requireNonNull(elements);
        if (elements.isEmpty()) {
            return this;
        } else {
            ArrayList nextUnderlying = getNextUnderlying();
            nextUnderlying.addAll(elements);

            return concreteVectorBuilder(nextUnderlying.size(), initialCapacity, nextUnderlying);
        }
    }

    @Override
    public NonEmptyVectorBuilder addAll(FiniteIterable elements) {
        Objects.requireNonNull(elements);
        if (elements.isEmpty()) {
            return this;
        } else {
            return addAllImpl(elements);
        }
    }

    @Override
    public NonEmptyVectorBuilder addAll(NonEmptyFiniteIterable elements) {
        return addAllImpl(elements);
    }

    @Override
    public ImmutableNonEmptyVector build() {
        return ImmutableVectors.wrapAndVouchFor(underlying).take(size).toNonEmptyOrThrow();
    }

    private NonEmptyVectorBuilder addAllImpl(Iterable elements) {
        ArrayList nextUnderlying = getNextUnderlying();
        for (A element : elements) {
            nextUnderlying.add(element);
        }

        return concreteVectorBuilder(nextUnderlying.size(), initialCapacity, nextUnderlying);
    }

    private ArrayList getNextUnderlying() {
        // If the size has changed, we need to make a copy
        if (underlying.size() == size) {
            return underlying;
        } else {
            ArrayList newUnderlying = initialCapacity.match(__ -> new ArrayList<>(), ArrayList::new);
            for (int i = 0; i < size; i++) {
                newUnderlying.add(underlying.get(i));
            }
            return newUnderlying;
        }
    }

    static  ConcreteVectorBuilder concreteVectorBuilder(int size, Maybe initialCapacity, ArrayList underlying) {
        assert (size >= 1);
        return new ConcreteVectorBuilder<>(size, initialCapacity, underlying);
    }

    static  ConcreteVectorBuilder concreteVectorBuilder(Maybe initialCapacity, A firstElement) {
        ArrayList underlying = initialCapacity.match(__ -> new ArrayList<>(), ArrayList::new);
        underlying.add(firstElement);
        return new ConcreteVectorBuilder<>(1, initialCapacity, underlying);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy