import java.util.*; import java.util.function.Predicate; import java.util.stream.Stream; import static java.util.stream.Collectors.toList; abstract class Example { interface PriceList {} List findByTags(List tags, Date date) { return copyOf(findMatching(tags).stream().filter(isActive(date)).collect(toList())); } protected abstract Predicate isActive(Date date); protected abstract List findMatching(List tags); protected abstract List copyOf(Collection e); }