MappedAccumulator.java
/*
* Java Genetic Algorithm Library (@__identifier__@).
* Copyright (c) @__year__@ Franz Wilhelmstötter
*
* Licensed 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.
*
* Author:
* Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
*/
package org.jenetics.util;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static org.jenetics.internal.util.object.eq;
import org.jenetics.internal.util.HashBuilder;
/**
* Abstract implementation of the {@link Accumulator} interface which defines a
* {@code samples} property which is incremented by the {@link #accumulate(Object)}
* method.
*
* @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
* @since 1.0
* @version 1.0 — <em>$Date: 2014-03-01 $</em>
*/
public abstract class MappedAccumulator<T>
implements
Accumulator<T>,
Cloneable
{
/**
* The number of accumulated samples.
*/
protected long _samples = 0;
protected MappedAccumulator() {
}
/**
* Return the number of samples accumulated so far.
*
* @return the number of samples accumulated so far.
*/
public long getSamples() {
return _samples;
}
@Override
public void accumulate(final T value) {
++_samples;
}
/**
* Return a view of this adapter with a different type {@code B}.
*
* Usage example:
* [code]
* // Convert a string on the fly into a double value.
* final Converter<String, Double> converter = new Converter<String, Double>() {
* public Double convert(final String value) {
* return Double.valueOf(value);
* }
* };
*
* // The values to accumulate
* final List<String> values = Arrays.asList("0", "1", "2", "3", "4", "5");
*
* final Accumulators.Min<Double> accumulator = new Accumulators.Min<Double>();
*
* // No pain to accumulate collections of a different type.
* Accumulators.accumulate(values, accumulator.map(converter));
* [/code]
*
* @param <B> the type of the returned adapter (view).
* @param mapper the mapper needed to map between the type of this
* adapter and the adapter view type.
* @return the adapter view with the different type.
* @throws NullPointerException if the given {@code converter} is {@code null}.
*/
public <B> MappedAccumulator<B> map(final Function<? super B, ? extends T> mapper) {
requireNonNull(mapper, "Mapper");
return new MappedAccumulator<B>() {
@Override
public void accumulate(final B value) {
MappedAccumulator.this.accumulate(mapper.apply(value));
}
};
}
@Override
public int hashCode() {
return HashBuilder.of(getClass()).and(_samples).value();
}
@Override
public boolean equals(final Object obj) {
if (obj == this) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final MappedAccumulator<?> accumulator = (MappedAccumulator<?>)obj;
return eq(_samples, accumulator._samples);
}
@Override
public String toString() {
return format(
"%s[samples=%d]", getClass().getName(), _samples
);
}
@SuppressWarnings("unchecked")
@Override
protected MappedAccumulator<T> clone() {
try {
return (MappedAccumulator<T>)super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
}