Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.functor.aggregator; import org.apache.commons.functor.BinaryFunction; /** * An implementation of an aggregator which doesn't store the data series but * instead it processes the data on the fly, as it arrives in * {@link #add(Object)} and stores the result after each addition. It processes * the data by using a {@link BinaryFunction} which takes the result of the * previous {@link #add(Object)} and the data passed in and returns a new result * which gets stored (for using again in the next call to {@link #add(Object)}. * The call to {@link #evaluate()} simply returns this stored value at any * point. This has a lower memory footprint compared to * {@link AbstractListBackedAggregator} however it only allows for simpler * processing on the data received. * * @param <T> * Type of object stored. */ public abstract class AbstractNoStoreAggregator<T> extends AbstractTimedAggregator<T> { /** * Function used to aggregate the data on the fly in {@link #add(Object)}. * * @see #add(Object) * @see #AbstractNoStoreAggregator(BinaryFunction) */ private BinaryFunction<T, T, T> aggregationFunction; /** * Stores the result of the last {@link #add(Object)} operation. * * @see #add(Object) */ private T result; /** * Similar to {@link #AbstractNoStoreAggregator(BinaryFunction, long) * AbstractNoStoreAggregator(aggregationFunction,0L)}. * * @param aggregationFunction * Aggregation function to use in {@link #add(Object)}. Throws * <code>NullPointerException</code> if this is <code>null</code> * @see #add(Object) * @see #aggregationFunction */ public AbstractNoStoreAggregator(BinaryFunction<T, T, T> aggregationFunction) { this(aggregationFunction, 0L); } /** * Similar to * {@link #AbstractNoStoreAggregator(BinaryFunction, long,boolean) * AbstractNoStoreAggregator(aggregationFunction,0L,false)}. * * @param aggregationFunction * Aggregation function to use in {@link #add(Object)}. Throws * <code>NullPointerException</code> if this is <code>null</code> * @param interval * interval in miliseconds to reset this aggregator * @see #add(Object) * @see #aggregationFunction */ public AbstractNoStoreAggregator(BinaryFunction<T, T, T> aggregationFunction, long interval) { this(aggregationFunction, interval, false); } /** * Constructs an aggregator which will use the given function, reset itself * at the given interval and will use a shared timer on own private timer. * Simply prepares an aggregator which will use the given aggregation * function each time {@link #add(Object)} is called. Also it initializes * {@link #result} with the value returned by {@link #initialValue()}, thus * allowing subclasses to have a custom way of specifying the start value. * * @param aggregationFunction * Aggregation function to use in {@link #add(Object)}. Throws * <code>NullPointerException</code> if this is <code>null</code> * @param interval * interval in miliseconds to reset this aggregator * @param useSharedTimer * if set to true, it will use a shared timer, as per * {@link AbstractTimedAggregator#AbstractTimedAggregator(long, boolean)} * ; otherwise if it's false it will use its own timer instance * @see AbstractTimedAggregator#AbstractTimedAggregator(long, boolean) */ public AbstractNoStoreAggregator(BinaryFunction<T, T, T> aggregationFunction, long interval, boolean useSharedTimer) { super(interval, useSharedTimer); this.aggregationFunction = aggregationFunction; result = initialValue(); } /** * Receives data to be aggregated/processed on the fly. This implementation * simply calls {@link #aggregationFunction} and stores the result. * * @param data * Data to aggregate */ @Override protected final void doAdd(T data) { result = aggregationFunction.evaluate(result, data); } /** * Returns the value already computed and stored in {@link #result}. * * @return Current (aggregated) value stored in {@link #result} * @see Aggregator#evaluate() */ @Override protected final T doEvaluate() { return result; } /** * Resets the {@link #result} member to the {@link #initialValue()}. * * @see #initialValue() */ @Override protected final void doReset() { result = initialValue(); } /** * Allows subclasses to define the "initial" value. This value will be * stored in {@link #result} when an instance of this class is created or * when {@link #reset()} is called. * * @return Initial value to be used in {@link #result}. */ protected abstract T initialValue(); /** * Getter for {@link #aggregationFunction}. * * @return Current value of the member. */ final BinaryFunction<T, T, T> getAggregationFunction() { return aggregationFunction; } /** * Getter for {@link #result}. Provided for test purposes only. * * @return Current value of the aggregated data. */ final T getResult() { return result; } /** * Setter for {@link #result}. Provided for test purposes only. * * @param result * New value to store in {@link #result} */ final void setResult(T result) { this.result = result; } /** * This aggregator doesn't store any data, so the data series size is always * 0 (zero). * * @return 0 */ @Override protected int retrieveDataSize() { return 0; } @Override public String toString() { return AbstractNoStoreAggregator.class.getName(); } }