package com.googlecode.totallylazy;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static com.googlecode.totallylazy.functions.Callables.size;
import static com.googlecode.totallylazy.predicates.Predicates.contains;
import static com.googlecode.totallylazy.Sequences.sequence;
import static java.util.Arrays.asList;
import static java.util.Collections.newSetFromMap;
public class Sets {
public static <T> Set<T> set() {
return new LinkedHashSet<T>();
}
@SafeVarargs
public static <T> Set<T> set(T... values) {
return set(new LinkedHashSet<T>(), values);
}
@SafeVarargs
public static <T, S extends Set<T>> S set(S result, T... values) {
return set(result, asList(values));
}
public static <T> Set<T> set(final Iterable<? extends T> iterable) {
return set(new LinkedHashSet<T>(), iterable);
}
public static <T, S extends Set<T>> S set(S result, final Iterable<? extends T> iterable) {
return set(result, iterable.iterator());
}
public static <T> Set<T> set(final Iterator<? extends T> iterator) {
return set(new LinkedHashSet<T>(), iterator);
}
public static <T, S extends Set<T>> S set(S result, final Iterator<? extends T> iterator) {
while (iterator.hasNext()) {
result.add(iterator.next());
}
return result;
}
public static <T> Set<T> fifoSet(final int maximumElements) {
return newSetFromMap(Maps.<T, Boolean>fifoMap(maximumElements));
}
public static <T> Set<T> union(final Set<? extends T> first, final Set<? extends T> second) {
return union(sequence(first, second));
}
public static <T> Set<T> union(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third) {
return union(sequence(first, second, third));
}
public static <T> Set<T> union(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third, final Set<? extends T> fourth) {
return union(sequence(first, second, third, fourth));
}
public static <T> Set<T> union(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third, final Set<? extends T> fourth, final Set<? extends T> firth) {
return union(sequence(first, second, third, fourth, firth));
}
@SafeVarargs
public static <T> Set<T> union(final Set<? extends T>... sets) {
return union(asList(sets));
}
public static <T> Set<T> union(final Iterable<? extends Set<? extends T>> sets) {
Set<T> result = new LinkedHashSet<T>();
for (Set<? extends T> set : sets) {
result.addAll(set);
}
return result;
}
public static <T> Set<T> intersection(final Set<? extends T> first, final Set<? extends T> second) {
return intersection(sequence(first, second));
}
public static <T> Set<T> intersection(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third) {
return intersection(sequence(first, second, third));
}
public static <T> Set<T> intersection(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third, final Set<? extends T> fourth) {
return intersection(sequence(first, second, third, fourth));
}
public static <T> Set<T> intersection(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third, final Set<? extends T> fourth, final Set<? extends T> firth) {
return intersection(sequence(first, second, third, fourth, firth));
}
@SafeVarargs
public static <T> Set<T> intersection(final Set<? extends T>... sets) {
return intersection(sequence(sets));
}
public static <T> Set<T> intersection(final Iterable<? extends Set<? extends T>> iterables) {
Sequence<Set<T>> sets = sequence(iterables).sortBy(size()).unsafeCast();
Set<T> smallest = sets.head();
Sequence<Set<T>> theRest = sets.tail();
Set<T> result = new LinkedHashSet<T>();
for (T t : smallest) {
if (theRest.forAll(contains(t))) {
result.add(t);
}
}
return result;
}
public static <T> Set<T> complement(final Set<? extends T> first, final Set<? extends T> second) {
return complement(sequence(first, second));
}
public static <T> Set<T> complement(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third) {
return complement(sequence(first, second, third));
}
public static <T> Set<T> complement(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third, final Set<? extends T> fourth) {
return complement(sequence(first, second, third, fourth));
}
public static <T> Set<T> complement(final Set<? extends T> first, final Set<? extends T> second, final Set<? extends T> third, final Set<? extends T> fourth, final Set<? extends T> firth) {
return complement(sequence(first, second, third, fourth, firth));
}
@SafeVarargs
public static <T> Set<T> complement(final Set<? extends T>... sets) {
return complement(asList(sets));
}
public static <T> Set<T> complement(final Iterable<? extends Set<? extends T>> iterables) {
Sequence<Set<T>> sets = sequence(iterables).unsafeCast();
Set<T> head = sets.head();
Sequence<Set<T>> theRest = sets.tail();
Set<T> result = new LinkedHashSet<T>();
result.addAll(head);
for (Set<T> set : theRest) {
result.removeAll(set);
}
return result;
}
public static <T> Set<T> concurrentSet() {
return newSetFromMap(new ConcurrentHashMap<T, Boolean>());
}
}