Ленивый пример c итераторами
Код на потестить, с лекции, с ленивыми функциями
public class Main {
// базовый интерфейс для ленивых иетраторов
interface SFn<T> extends Iterable<T> {
/*
* Функция для отображения одного итератора в другой
*/
default <R> SFn<R> map(Function<T, R> func) {
Iterator<T> baseIterator = this.iterator();
return () -> new Iterator<R>() {
public boolean hasNext() {
// новый итератор синхронизирован с базовым
// и двигается синхронно с ним
return baseIterator.hasNext();
}
public R next() {
// очередное значение итератора считается
// путем применения функции func к значению базового итератора
return func.apply(baseIterator.next());
}
};
}
/*
* Функция для фильтрации данных итератора
* на вход принимает булеву функцию
* которая вохвращает true если значение подходит и false если не подходит
*/
default SFn<T> filter(Function<T, Boolean> func) {
Iterator<T> baseIterator = this.iterator(); // выковыриваем базовый итератор
return () -> new Iterator<T>() {
T currentValue; // для хранения текущего значения итератора
public boolean hasNext() {
// сдвиг нового итератора не синхронен с базой
boolean hasNext = baseIterator.hasNext(); // проверяем есть ли вообще значения в базе
if (hasNext) { // если есть
do {
T value = baseIterator.next(); // вытаскиваем очередное значение базы
if (func.apply(value)) { // проверяем выдает ли для него func значение true
currentValue = value; // если да, то фиксируем это значение
return true; // и возвращаем true, что означает что у нового итератора есть значения
}
} while (baseIterator.hasNext()); // иначе сдвигаем базу вправо
}
return false; // если ничего не нашли
}
public T next() {
// если сюда попали, значит hasNext нового итератора
// нашел очередное значение базы удволетворяюще func
// в hasNext мы его зафиксировали
return currentValue; // а тут возвращаем
}
};
}
}
// обертка над списком
public static class SFnList<T> implements SFn<T> {
ArrayList<T> list;
public SFnList(ArrayList<T> list) {
this.list = list; // пробрасываем список внутрь класса
}
public Iterator<T> iterator() {
// пробрасываем итератор внутренего списка во вне
return list.iterator();
}
}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(6);
list.add(7);
list.add(8);
list.add(9);
SFnList<Integer> fnList = new SFnList<>(list);
/*
* оставляем из списка только значения больше 5
* и заменяем их на чет/нечет в зависимости от остатка от деления
*
* останутся только значения 6,7,8,9
* которые привратятся в [чет,нечет,чет,нечет]
*/
for (String s : fnList.filter(x -> x > 5).map(x -> x % 2 == 0 ? "чет" : "нечет")) {
System.out.println(s);
}
}
}