/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.sets;

import java.util.ArrayList;
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.BinaryOperator;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public interface MultiSet<K> extends Set<K> {
    
    @SuppressWarnings("rawtypes")
    MultiSet EMPTY = new SetUtils.EmptyMS();
    
    Collection<K> getAll(Object key);
    
    default K get(Object key, BinaryOperator<K> fold) {
        return getAll(key).stream().reduce(fold).orElseThrow(()->new NoSuchElementException());
    }

    default Collection<K> removeAll(Object key) {
        Collection<K> out = new ArrayList<>(getAll(key));
        for(K k : out) {
            remove(k);
        }
        return out;
    }
    
    default Set<K> uniqueSet() {
        return new HashSet<>(this);
    }

    @SuppressWarnings("unchecked")
    static <K> MultiSet<K> empty() {
        return EMPTY;
    }
}
