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

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

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

import org.jhotdraw8.icollection.readonly.ReadOnlySet;
import org.jspecify.annotations.Nullable;

import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * Provides a {@link Set} facade to a set of {@code Set} functions.
 *
 * @param  the element type
 * @author Werner Randelshofer
 */
public class SetFacade extends AbstractSet implements ReadOnlySet {
    protected final Supplier> iteratorFunction;
    protected final Supplier> spliteratorFunction;
    protected final IntSupplier sizeFunction;
    protected final Predicate containsFunction;
    protected final Predicate addFunction;
    protected final Runnable clearFunction;
    protected final Predicate removeFunction;

    public SetFacade(ReadOnlySet backingSet) {
        this(backingSet::iterator, backingSet::spliterator, backingSet::size,
                backingSet::contains, null, null, null);
    }

    public SetFacade(Set backingSet) {
        this(backingSet::iterator,
                backingSet::spliterator,
                backingSet::size,
                backingSet::contains, backingSet::clear, backingSet::add, backingSet::remove);
    }

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

    public SetFacade(Supplier> iteratorFunction,
                     Supplier> spliteratorFunction,
                     IntSupplier sizeFunction,
                     Predicate containsFunction,
                     @Nullable Runnable clearFunction,
                     @Nullable Predicate addFunction,
                     @Nullable Predicate removeFunction) {
        this.iteratorFunction = iteratorFunction;
        this.spliteratorFunction = spliteratorFunction;
        this.sizeFunction = sizeFunction;
        this.containsFunction = containsFunction;
        this.clearFunction = clearFunction == null ? () -> {
            throw new UnsupportedOperationException();
        } : clearFunction;
        this.removeFunction = removeFunction == null ? o -> {
            throw new UnsupportedOperationException();
        } : removeFunction;
        this.addFunction = addFunction == null ? o -> {
            throw new UnsupportedOperationException();
        } : addFunction;

    }

    @Override
    public boolean remove(Object o) {
        return removeFunction.test(o);
    }

    @Override
    public void clear() {
        clearFunction.run();
    }

    @Override
    public Spliterator spliterator() {
        return spliteratorFunction.get();
    }

    @Override
    public Stream stream() {
        return super.stream();
    }

    @Override
    public Iterator iterator() {
        return iteratorFunction.get();
    }

    @Override
    public boolean equals(Object o) {
        return super.equals(o);
    }

    @Override
    public int size() {
        return sizeFunction.getAsInt();
    }

    @Override
    public boolean contains(Object o) {
        return containsFunction.test(o);
    }

    @Override
    public boolean add(E e) {
        return addFunction.test(e);
    }
}