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

nl.vpro.util.SortedSetElementWrapper Maven / Gradle / Ivy

There is a newer version: 5.3.1
Show newest version
package nl.vpro.util;

import java.util.AbstractSet;
import java.util.Comparator;
import java.util.Iterator;
import java.util.SortedSet;

import org.checkerframework.checker.nullness.qual.NonNull;

/**
 * @author Michiel Meeuwissen
 * @since 2.3.1
 */
public abstract class SortedSetElementWrapper extends AbstractSet implements SortedSet {

    protected final SortedSet wrapped;

    public SortedSetElementWrapper(SortedSet wrapped) {
        if (wrapped == null) {
            throw new IllegalArgumentException("Cannot wrap null");
        }
        this.wrapped = wrapped;
    }

    @NonNull
    @Override
    public Iterator iterator() {
        return new Iterator() {
            final Iterator iterator = wrapped.iterator();
            @Override
            public boolean hasNext() {
                return iterator.hasNext();

            }

            @Override
            public S next() {
                return adapt(iterator.next());

            }

            @Override
            public void remove() {
                iterator.remove();

            }
        };
    }


    @Override
    public int size() {
        return wrapped.size();

    }

    @Override
    public Comparator comparator() {
        return (Comparator) (o1, o2) -> wrapped.comparator().compare(find(o1), find(o2));

    }

    @NonNull
    @Override
    public SortedSet subSet(S fromElement, S toElement) {
        return sub(wrapped.subSet(find(fromElement), find(toElement)));
    }

    @NonNull
    @Override
    public SortedSet headSet(S toElement) {
        return sub(wrapped.headSet(find(toElement)));

    }

    @NonNull
    @Override
    public SortedSet tailSet(S fromElement) {
        return sub(wrapped.tailSet(find(fromElement)));
    }

    @Override
    public S first() {
        return adapt(wrapped.first());

    }

    @Override
    public S last() {
        return adapt(wrapped.last());
    }

    protected SortedSet sub(SortedSet wrapped) {
        return new SortedSetElementWrapper(wrapped) {
            @Override
            protected S adapt(T element) {
                return SortedSetElementWrapper.this.adapt(element);

            }
        };
    }

    protected T find(S element) {
        for (T t : wrapped) {
            if (adapt(t).equals(element)) {
                return t;
            }
        }
        return null;
    }


    protected abstract S adapt(T element);
}