/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.calc.runner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.DoubleStream;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.MultiCurrencyAmount;
import com.opengamma.strata.calc.Measure;
import com.opengamma.strata.collect.result.Result;
import com.opengamma.strata.data.scenario.CurrencyScenarioArray;
import com.opengamma.strata.data.scenario.DoubleScenarioArray;
import com.opengamma.strata.data.scenario.MultiCurrencyScenarioArray;
import com.opengamma.strata.data.scenario.ScenarioArray;
/**
* Static utility methods useful when writing calculation functions.
*/
public final class FunctionUtils {
// Private constructor because this only contains static helper methods.
private FunctionUtils() {
}
/**
* Returns a collector which can be used at the end of a stream of results to build a {@link ScenarioArray}.
*
* @param <T> the type of the results in the stream
* @return a collector used to create a {@code CurrencyAmountList} from a stream of {@code CurrencyAmount}
*/
public static <T> Collector<T, List<T>, ScenarioArray<T>> toScenarioArray() {
// edited to compile in Eclipse
return Collector.of(
ArrayList<T>::new,
(a, b) -> a.add(b),
(l, r) -> {
l.addAll(r);
return l;
},
list -> buildResult(list));
}
@SuppressWarnings("unchecked")
private static <T, R> ScenarioArray<T> buildResult(List<T> results) {
return ScenarioArray.of(results);
}
//-------------------------------------------------------------------------
/**
* Returns a collector that builds a multi-currency scenerio result.
* <p>
* This is used at the end of a stream to collect per-scenario instances of {@link MultiCurrencyAmount}
* into a single instance of {@link MultiCurrencyScenarioArray}, which is designed to be space-efficient.
*
* @return a collector used at the end of a stream of {@link MultiCurrencyAmount}
* to build a {@link MultiCurrencyScenarioArray}
*/
public static
Collector<MultiCurrencyAmount, List<MultiCurrencyAmount>, MultiCurrencyScenarioArray> toMultiCurrencyValuesArray() {
return Collector.of(
ArrayList<MultiCurrencyAmount>::new,
(a, b) -> a.add(b),
(l, r) -> {
l.addAll(r);
return l;
},
list -> MultiCurrencyScenarioArray.of(list));
}
/**
* Returns a collector that builds a single-currency scenerio result.
* <p>
* This is used at the end of a stream to collect per-scenario instances of {@link CurrencyAmount}
* into a single instance of {@link CurrencyScenarioArray}, which is designed to be space-efficient.
*
* @return a collector used at the end of a stream of {@link CurrencyAmount} to build a {@link CurrencyScenarioArray}
*/
public static Collector<CurrencyAmount, List<CurrencyAmount>, CurrencyScenarioArray> toCurrencyValuesArray() {
return Collector.of(
ArrayList<CurrencyAmount>::new,
(a, b) -> a.add(b),
(l, r) -> {
l.addAll(r);
return l;
},
list -> CurrencyScenarioArray.of(list));
}
/**
* Returns a collector that builds a scenario result based on {@code Double}.
* <p>
* This is used at the end of a stream to collect per-scenario instances of {@code Double}
* into a single instance of {@link DoubleScenarioArray}, which is designed to be space-efficient.
* <p>
* Note that {@link DoubleStream} does not support collectors, which makes this less efficient
* than it should be.
*
* @return a collector used at the end of a stream of {@link Double} to build a {@link DoubleScenarioArray}
*/
public static Collector<Double, List<Double>, DoubleScenarioArray> toValuesArray() {
return Collector.of(
ArrayList<Double>::new,
(a, b) -> a.add(b),
(l, r) -> {
l.addAll(r);
return l;
},
list -> DoubleScenarioArray.of(list));
}
/**
* Checks if a map of results contains a value for a key, and if it does inserts it into the map for a different key.
*
* @param existingKey a key for which the map possibly contains a value
* @param newKey the key which is inserted into the map
* @param mutableMeasureMap a mutable map of values, keyed by measure
*/
public static void duplicateResult(Measure existingKey, Measure newKey, Map<Measure, Result<?>> mutableMeasureMap) {
Result<?> result = mutableMeasureMap.get(existingKey);
if (result == null) {
return;
}
mutableMeasureMap.put(newKey, result);
}
}