/** * 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); } }