Skip to content
Snippets Groups Projects
Commit 0d5d262c authored by Daniel Schramm's avatar Daniel Schramm
Browse files

Collector for computation of the weighted average implemented

parent f5ee16b8
No related branches found
No related tags found
No related merge requests found
package cz.fidentis.analyst.visitors.face;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.stream.Collector;
/**
* A collector for computing weighted average suitable for use in Java 8 streams.
*
* <p>
* A mutable reduction operation that accumulates input elements into a mutable
* result container, optionally transforming the accumulated result into a final
* representation after all input elements have been processed.
* </p>
*
* @author Daniel Schramm
* @param <T> Data type of the stream elements
*/
public class WeightedAverageCollector<T> implements Collector<T, IntemediateResults, Double> {
private final ToDoubleFunction<? super T> valueFunction, weightFunction;
/**
* Constructor.
*
* @param valueFunction Function returning the value for a given stream element
* @param weightFunction Function returning the weight for a given stream element
*/
public WeightedAverageCollector(
ToDoubleFunction<? super T> valueFunction,
ToDoubleFunction<? super T> weightFunction) {
this.valueFunction = valueFunction;
this.weightFunction = weightFunction;
}
/**
* Returns a {@link Collector} interface object used to compute the weighted average.
*
* @param <T> Data type of the stream elements
* @param valueFunction Function returning the value for a given stream element
* @param weightFunction Function returning the weight for a given stream element
* @return A Collector interface object used to compute the weighted average
*/
public static <T> Collector<T, ?, Double> toWeightedAverage(
ToDoubleFunction<? super T> valueFunction,
ToDoubleFunction<? super T> weightFunction) {
return new WeightedAverageCollector(valueFunction, weightFunction);
}
/**
* A function that creates and returns a new mutable result container.
*
* @return A function which returns a new, mutable result container
*/
@Override
public Supplier<IntemediateResults> supplier() {
return IntemediateResults::new;
}
/**
* A function that folds a value into a mutable result container.
*
* @return A function which folds a value into a mutable result container
*/
@Override
public BiConsumer<IntemediateResults, T> accumulator() {
return (result, streamElement) -> {
result.weightedValSum += valueFunction.applyAsDouble(streamElement)
* weightFunction.applyAsDouble(streamElement);
result.weightSum += weightFunction.applyAsDouble(streamElement);
};
}
/**
* A function that accepts two partial results and merges them. The
* combiner function may fold state from one argument into the other and
* return that, or may return a new result container.
*
* @return A function which combines two partial results into a combined
* result
*/
@Override
public BinaryOperator<IntemediateResults> combiner() {
return (result1, result2) -> {
result1.weightedValSum += result2.weightedValSum;
result1.weightSum += result2.weightSum;
return result1;
};
}
/**
* Perform the final transformation from the intermediate accumulation type
* {@code A} to the final result type {@code R}.
*
* <p>
* If the characteristic {@code IDENTITY_FINISH} is
* set, this function may be presumed to be an identity transform with an
* unchecked cast from {@code A} to {@code R}.
* </p>
*
* @return A function which transforms the intermediate result to the final
* result
*/
@Override
public Function<IntemediateResults, Double> finisher() {
return result -> result.weightedValSum / result.weightSum;
}
/**
* Returns a {@code Set} of {@code Collector.Characteristics} indicating
* the characteristics of this Collector.
*
* @return An immutable set of collector characteristics
*/
@Override
public Set<Characteristics> characteristics() {
return Set.of(Characteristics.UNORDERED);
}
}
/**
* A helper class which stores intermediate results
* for the {@link WeightedAverageCollector} class.
*
* @author Daniel Schramm
*/
class IntemediateResults {
double weightedValSum = 0;
double weightSum = 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment