UnmodifiableCollectionBuilder.java

/*
 * Copyright (C) 2018 Stein Eldar Johnsen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.morimekta.collect;

import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;

/**
 * Base interface for unmodifiable collections.
 *
 * @param <E> The collection element type.
 * @param <C> The collection type.
 * @param <B> The builder type.
 */
public interface UnmodifiableCollectionBuilder<
        E,
        C extends UnmodifiableCollection<E>,
        B extends UnmodifiableCollectionBuilder<E, C, B>> {
    /**
     * Build the collection.
     *
     * @return The collection instance.
     */
    C build();

    /**
     * Add a single element to the collection.
     *
     * @param e The element to add.
     * @return The builder.
     */
    B add(E e);

    /**
     * Add any number of elements to the collection.
     *
     * @param items All the elements to add.
     * @return The builder.
     */
    @SuppressWarnings("unchecked")
    B addAll(E... items);

    /**
     * Add all elements from source collection to this collection.
     *
     * @param collection The source collection.
     * @return The builder.
     */
    B addAll(Collection<? extends E> collection) ;

    /**
     * Add all items from iterator to collection.
     *
     * @param iterator The iterator to get items from.
     * @return The builder.
     */
    @SuppressWarnings("unchecked")
    default B addAll(Iterator<? extends E> iterator) {
        iterator.forEachRemaining(this::add);
        return (B) this;
    }

    /**
     * Add all items in an iterable to the collection.
     *
     * @param iterable Iterable instance to get items from.
     * @return The builder.
     */
    default B addAll(Iterable<? extends E> iterable) {
        if (iterable instanceof Collection) {
            return addAll((Collection<? extends E>) iterable);
        }
        return addAll(iterable.iterator());
    }

    /**
     * Add all items from enumeration to collection.
     *
     * @param enumeration The source enumeration.
     * @return The builder.
     */
    @SuppressWarnings("unchecked")
    default B addAll(Enumeration<? extends E> enumeration) {
        while (enumeration.hasMoreElements()) {
            add(enumeration.nextElement());
        }
        return (B) this;
    }
}