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

org.jhotdraw8.icollection.facade.SequencedSetFacade Maven / Gradle / Ivy

The newest version!
/*
 * @(#)SequencedSetFacade.java
 * Copyright © 2023 The authors and contributors of JHotDraw. MIT License.
 */
package org.jhotdraw8.icollection.facade;

import org.jhotdraw8.icollection.readonly.ReadOnlyCollection;
import org.jhotdraw8.icollection.readonly.ReadOnlySequencedCollection;
import org.jhotdraw8.icollection.sequenced.ReversedSequencedSetView;
import org.jspecify.annotations.Nullable;

import java.util.Iterator;
import java.util.SequencedSet;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * Provides a {@link SequencedSet} facade to a set of {@code Set} functions.
 *
 * @param  the element type
 * @author Werner Randelshofer
 */
public class SequencedSetFacade extends SetFacade implements SequencedSet {

    private final Supplier getFirstFunction;
    private final Supplier getLastFunction;
    private final Consumer addFirstFunction;
    private final Consumer addLastFunction;
    private final Supplier> reverseIteratorFunction;
    private final Supplier> reverseSpliteratorFunction;
    private final Predicate reversedAddFunction;

    public SequencedSetFacade(ReadOnlyCollection backingSet,
                              Supplier> reverseIteratorFunction) {
        this(backingSet::iterator, backingSet::spliterator,
                reverseIteratorFunction,
                () -> Spliterators.spliterator(reverseIteratorFunction.get(), backingSet.size(), Spliterator.DISTINCT),
                backingSet::size,
                backingSet::contains, null, null, null, null, null, null, null, null);
    }

    public SequencedSetFacade(ReadOnlySequencedCollection backingSet) {
        this(backingSet::iterator, backingSet::spliterator, () -> backingSet.readOnlyReversed().iterator(),
                () -> backingSet.readOnlyReversed().spliterator(), backingSet::size,
                backingSet::contains, null, null,
                backingSet::getFirst,
                backingSet::getLast,
                null, null, null, null);
    }

    public SequencedSetFacade(Set backingSet,
                              Supplier> reverseIteratorFunction) {
        this(backingSet::iterator, backingSet::spliterator,
                reverseIteratorFunction, () -> Spliterators.spliterator(reverseIteratorFunction.get(), backingSet.size(), Spliterator.DISTINCT), backingSet::size,
                backingSet::contains, backingSet::clear, backingSet::remove, null, null, null, null, null, null);
    }

    public SequencedSetFacade(Supplier> iteratorFunction,
                              Supplier> reverseIteratorFunction,
                              IntSupplier sizeFunction,
                              Predicate containsFunction) {
        this(iteratorFunction,
                () -> Spliterators.spliterator(iteratorFunction.get(), sizeFunction.getAsInt(), Spliterator.DISTINCT), reverseIteratorFunction,
                () -> Spliterators.spliterator(reverseIteratorFunction.get(), sizeFunction.getAsInt(), Spliterator.DISTINCT),
                sizeFunction, containsFunction, null, null, null, null, null, null, null, null);
    }

    public SequencedSetFacade(Supplier> iteratorFunction,
                              Supplier> spliteratorFunction,
                              Supplier> reverseIteratorFunction,
                              Supplier> reverseSpliteratorFunction,
                              IntSupplier sizeFunction,
                              Predicate containsFunction,
                              @Nullable Runnable clearFunction,
                              @Nullable Predicate removeFunction,
                              @Nullable Supplier getFirstFunction,
                              @Nullable Supplier getLastFunction,
                              @Nullable Predicate addFunction,
                              @Nullable Predicate reversedAddFunction,
                              @Nullable Consumer addFirstFunction,
                              @Nullable Consumer addLastFunction) {
        super(iteratorFunction, spliteratorFunction, sizeFunction, containsFunction, clearFunction, addFunction, removeFunction);
        Supplier throwingSupplier = () -> {
            throw new UnsupportedOperationException();
        };
        this.getFirstFunction = getFirstFunction == null ? throwingSupplier : getFirstFunction;
        this.getLastFunction = getLastFunction == null ? throwingSupplier : getLastFunction;
        Consumer throwingConsumer = e -> {
            throw new UnsupportedOperationException();
        };
        Predicate throwingPredicate = e -> {
            throw new UnsupportedOperationException();
        };
        this.addFirstFunction = addFirstFunction == null ? throwingConsumer : addFirstFunction;
        this.addLastFunction = addLastFunction == null ? throwingConsumer : addLastFunction;
        this.reversedAddFunction = reversedAddFunction == null ? throwingPredicate : reversedAddFunction;
        this.reverseIteratorFunction = reverseIteratorFunction;
        this.reverseSpliteratorFunction = reverseSpliteratorFunction;
    }

    @Override
    public void addFirst(E e) {
        addFirstFunction.accept(e);
    }

    @Override
    public void addLast(E e) {
        addLastFunction.accept(e);
    }

    @Override
    public E removeLast() {
        E e = getLastFunction.get();
        removeFunction.test(e);
        return e;
    }

    @Override
    public E getFirst() {
        return getFirstFunction.get();
    }

    @Override
    public E getLast() {
        return getLastFunction.get();
    }

    @Override
    public SequencedSet reversed() {
        return new ReversedSequencedSetView<>(this, reverseIteratorFunction, reverseSpliteratorFunction);
    }
}