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

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

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

import java.io.Serial;
import java.io.Serializable;
import java.util.*;
import java.util.function.Consumer;

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

/**
 * A modifiable SortedSet, that wraps another collection (changes are reflected), with an explicit sort order.
 * @author Michiel Meeuwissen
 * @since 2.1
 */
public class ResortedSortedSet extends AbstractSet implements SortedSet, Serializable {

    @Serial
    private static final long serialVersionUID = 0L;

    final Collection wrapped;
    final SortedSet set;
    final Consumer[] addListeners;

    @SafeVarargs
    public ResortedSortedSet(Collection wrapped, Comparator comparator, Consumer... addListeners) {
        set = new TreeSet<>(comparator);
        set.addAll(wrapped);
        this.wrapped = wrapped;
        this.addListeners = addListeners;
    }

    @SafeVarargs
    private ResortedSortedSet(Collection wrapped, SortedSet set, Consumer... addListeners) {
        this.set = set;
        set.addAll(wrapped);
        this.wrapped = wrapped;
        this.addListeners = addListeners;
    }

    public static > ResortedSortedSet of(
        Collection wrapped, Consumer... addListener) {
        return new ResortedSortedSet<>(wrapped, new TreeSet<>(), addListener);
    }

    @SafeVarargs
    public ResortedSortedSet(SortedSet set, Collection wrapped, Consumer... addListeners) {
        this.set = set;
        this.wrapped = wrapped;
        this.addListeners = addListeners;
    }

    @NonNull
    @Override
    public Iterator iterator() {
        final Iterator i = set.iterator();
        return new Iterator() {

            T lastElement;
            boolean hasElementToRemove = false;

            @Override
            public boolean hasNext() {
                return i.hasNext();
            }

            @Override
            public T next() {
                lastElement = i.next();
                hasElementToRemove = true;
                return lastElement;
            }

            @Override
            public void remove() {
                i.remove();
                if (hasElementToRemove) {
                    wrapped.remove(lastElement);
                    hasElementToRemove = false;
                } else {
                    throw new IllegalStateException();
                }
            }
        };

    }

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

    }
    @Override
    public boolean add(T element) {
        boolean result = set.add(element);
        if (result) {
            wrapped.add(element);
            for (Consumer addListener : addListeners) {
                addListener.accept(element);
            }
        }
        return result;
    }

    @Override
    public Comparator comparator() {
        return set.comparator();

    }

    @NonNull
    @Override
    public SortedSet subSet(T fromElement, T toElement) {
        return new ResortedSortedSet<>(set.subSet(fromElement, toElement), wrapped);

    }

    @NonNull
    @Override
    public SortedSet headSet(T toElement) {
        return new ResortedSortedSet<>(set.headSet(toElement), wrapped);
    }

    @NonNull
    @Override
    public SortedSet tailSet(T fromElement) {
        return new ResortedSortedSet<>(set.tailSet(fromElement), wrapped);
    }

    @Override
    public T first() {
        return set.first();
    }

    @Override
    public T last() {
        return set.last();
    }
}