Мой вопрос содержит 2 подвопроса, поэтому он не ограничивается java, а учитывает парадигмы программирования в целом.
Мне нужен цикл, который выполняет обычный forEach, но также предоставляет для каждого индекса его предыдущие запуски. Позвольте мне уточнить.
Давайте определим:
ОБЪЕКТЫ = набор X, где X — любой тип объекта/данных.
PREV = результаты предыдущих итераций в виде коллекции Y, где Y является результатом одной итерации X< /сильный>
что бы сделал "мой" supplementalForEach:
OBJECTS.supplementalForEach((PREV, OBJ) -> doStuff(PREV, OBJ))
или как не потоковый вариант
var PREV = new ArrayList<>();
for(var OBJ : OBJECTS) {
var result = doStuff(PREV, OBJ);
PREV.add(result);
}
Таким образом, по сути, в Java это будет forEach, взяв BiFunction‹R, T› вместо Consumer‹T›
Теперь вопрос в том, существует ли уже концепция программирования для этой идеи? Если да, то как он называется? И если да, есть ли реализация Java?
Если нет, я могу просто реализовать это сам, но это мой любопытный вопрос. Кстати, я еще ничего не нашел в Google и Stackoverflow.
EDIT2: на данный момент я реализовал эти методы, не стесняйтесь использовать их по своему усмотрению (сохраняйте комментарии и ссылки)
/**
* @author levent.dag
* https://stackoverflow.com/users/9648047/levent-dag
*
* naming idea with "akuzminykh"
* https://stackoverflow.com/users/12323248/akuzminykh , 02.06.2020
*
* <pre>
* Cumulative Iteration:
* the process of iterating with the results of the previous iterations
*
* definition:
* D domain (collection of X)
* X ∈ of domain, Data/Object/Value
* R results of previous iterations (List<Y>)
*
* f(R, X) iteration cycle/Function for current X element with the knowledge of previous iteration results R
*
*
* for X ∈ D {
* R.add(R, X)
* }
*
* ORDER sensible! use ordered Collections such as Lists and so on.
* </pre>
* @param <X>
* @param <Y>
* @param col
* @param loopIteration
*/
public static <X, Y, LIST extends List<Y>> void cumulativeIteration(final Collection<X> col, final BiFunction<List<Y>, X, Y> loopIteration, Class<Y> clazz) {
final ArrayList<Y> previous = new ArrayList<>();
col.forEach(x -> previous.add(loopIteration.apply(previous, x)));
}
/**
* @author levent.dag
* https://stackoverflow.com/users/9648047/levent-dag
*
* naming idea with "akuzminykh"
* https://stackoverflow.com/users/12323248/akuzminykh , 02.06.2020
*
* Same as {@link Essentials#additiveIteration(Collection, BiFunction)}, but the previous results can be mapped.
*
* @param <X>
* @param <Y>
* @param col
* @param loopIteration
* @param mapper
*/
public static <X, Y> void mappedCumulativeIteration(final Collection<X> col, final BiFunction<Map<String, Y>, X, Y> loopIteration, final Function<X, String> mapper) {
final Map<String, Y> previous = new LinkedHashMap<>();
col.forEach(x -> previous.put(mapper.apply(x), loopIteration.apply(previous, x)));
}
кроме того, как указал @daniu, вы можете добиться этого с помощью сборщика, если хотите собрать данные.
col.stream().<List<Y>>collect(()->new ArrayList<>(), (pre, current) -> pre.add(loopIteration.apply(pre, current)), List::addAll);
Или как самостоятельный коллектор
/**
* @author levent.dag
* https://stackoverflow.com/users/9648047/levent-dag
*
* naming idea with "akuzminykh"
* https://stackoverflow.com/users/12323248/akuzminykh , 02.06.2020
*
* <pre>
* Cumulative Iteration:
* the process of iterating with the results of the previous iterations
*
* definition:
* D domain (collection of X)
* X ∈ of domain, Data/Object/Value
* R results of previous iterations (List<Y>)
*
* f(R, X) iteration cycle/Function for current X element with the knowledge of previous iteration results R
*
*
* for X ∈ D {
* R.add(R, X)
* }
*
* ORDER sensible! use ordered Collections such as Lists and so on.
* </pre>
*
* @param <OBJECT>
* @param <RESULT>
*/
public class CumulativeListCollector<OBJECT, RESULT> implements Collector<OBJECT, List<RESULT>, List<RESULT>> {
private final BiFunction<List<RESULT>, OBJECT, RESULT> loopIteration;
public CumulativeListCollector(final BiFunction<List<RESULT>, OBJECT, RESULT> loopIteration) {
this.loopIteration = loopIteration;
}
public static <O,R> CumulativeListCollector<O, R> of(final BiFunction<List<R>, O, R> loopIteration) {
return new CumulativeListCollector<>(loopIteration);
}
@Override
public Supplier<List<RESULT>> supplier() {
return ()->new ArrayList<RESULT>();
}
@Override
public BiConsumer<List<RESULT>, OBJECT> accumulator() {
return (pre, current) -> pre.add(this.loopIteration.apply(pre, current));
}
@Override
public Function<List<RESULT>, List<RESULT>> finisher() {
return Function.identity();
}
@Override
public BinaryOperator<List<RESULT>> combiner() {
return (left, right)->{left.addAll(right); return left;};
}
@Override
public Set<Characteristics> characteristics() {
return Set.of();
}
}