package com.googlecode.totallylazy.predicates; import com.googlecode.totallylazy.functions.Lazy; import com.googlecode.totallylazy.Sequences; import com.googlecode.totallylazy.Unchecked; import com.googlecode.totallylazy.annotations.multimethod; import java.util.Set; import static com.googlecode.totallylazy.predicates.Predicates.never; import static com.googlecode.totallylazy.Sequences.sequence; public class InPredicate<T> extends LogicalPredicate<T> { private final Iterable<T> original; private final Lazy<Set<T>> set; private InPredicate(final Iterable<T> iterable) { this.set = new Lazy<Set<T>>() { @Override protected Set<T> get() throws Exception { return set(iterable); } }; this.original = iterable; } @SafeVarargs public static <T> LogicalPredicate<T> in(final T... items) { return in(Sequences.sequence(items)); } public static <T> LogicalPredicate<T> in(final Iterable<? extends T> iterable) { if(Sequences.isEmpty(iterable)) return never(); return new InPredicate<T>(Unchecked.<Iterable<T>>cast(iterable)); } private Set<T> set(Iterable<T> iterable) { if(iterable instanceof Set) return (Set<T>) iterable; return sequence(iterable).toSet(); } public boolean matches(T other) { return set.value().contains(other); } // Used by LazyRecords, do not inline or change public Iterable<T> values() { return original; } @Override public String toString() { return sequence(original).toString("in('", "','", "')"); } @multimethod public boolean equals(InPredicate other) { return Sequences.equalTo(values(), other.values()); } @Override public int hashCode() { return sequence(values()).hashCode(); } }