Это можно сделать на чистом Java, но вам нужно написать класс поддержки Filter для следующего кода, который будет успешно выполняться:
List<Integer> oldList = Arrays.asList(new Integer[] { 1, 2, 5, 6, 9 });
List<Integer> newList = new Filter<Integer>(oldList) {
{
findAll(it > 5);
}
}.values();
System.out.println(newList); // [6, 9]
В случае, если вам интересно, почему этот код компилирует, обратите внимание на Скрытые возможности Java : инициализация с двойной скобкой. Это создает анонимный экземпляр класса Filter, который содержит переменную it и предоставляет метод findAll ().
У самого класса Filter есть один недостаток, заключающийся в том, что для каждого элемента списка создается новый экземпляр для оценки логического условия при findAll ():
public abstract class Filter<T> {
protected List<T> values = new ArrayList<T>();
protected T it;
public Filter(List<T> values) {
if (values != null) {
this.values.addAll(values);
}
if (values.isEmpty()) {
throw new RuntimeException("Not for empty collections!");
}
it = values.iterator().next();
// instance initializer gets executed here, calls findAll
}
protected void findAll(boolean b) throws Throwable {
// exit condition for future calls
if (values.size() > 1) {
// only repeat for each entry, if values has multiple entries
Iterator<T> iterator = values.iterator();
while (iterator.hasNext()) {
// don't evalute again for the first entry
if (!b) {
iterator.next();
iterator.remove();
b = true;
} else {
// for each other entry create an argument with one element
List<T> next = new ArrayList<T>();
next.add(iterator.next());
// get constructor of anonymous class
Constructor<?> constructor = this.getClass().getDeclaredConstructors()[0];
// invoke constructor and thus execute instance initializer again
Filter<T> filtered = (Filter<T>) constructor.newInstance(new Object[] { null, next });
// if values is empty, the condition didn't match and the element can be removed
if (filtered.values.isEmpty()) {
iterator.remove();
}
}
}
} else {
// one element can be checked directly
if (!b) {
values.clear();
}
}
}
public List<T> values() {
return values;
}
}
Но поскольку создание экземпляров в наши дни довольно дешево, а класс Filter можно использовать для всех объектов, возможно, стоит включить его в свой пакет Utils.
Greetz,
GHAD