Sorry, I don't think the title I wrote is correct and explains well what I'm asking, but at the moment I have not found better
I'm trying to change my approach from imperative to functional-programming in Java, sometime is easy but in other case no much... But I'm not giving up :)
I have a map of values that should be decreased of an amount calculated by a function, and for each input the are one or more functions that could be applied, what has been decreased by the previous function is "visible" to the next function, so something like that
Map<String, Double> input = new HashMap<>() {{
put("IN1", 100.0);
put("IN2", 10.0);
}};
Map<String, List<Function<Double, Double>>> rules = Map.of(
"IN1", List.of(value -> value / 10.0, value -> 80.0, value -> 10.0),
"IN2", List.of(value -> 2.0),
"IN3", List.of(value -> value / 5.0));
In imperative "style", I solve this using a function like that
for (Map.Entry<String, List<Function<Double, Double>>> entry : rules.entrySet()) {
String inName = entry.getKey();
Double inValue = input.get(inName);
if (inValue==null) continue;
for (Function<Double, Double> function : entry.getValue()) {
inValue -= function.apply(inValue);
if (inValue <= 0F) break;
}
input.put(inName, inValue);
}
What should be the right way in functional programming?
Thanks in advance :)
EDIT
The only solution I found is the following
Map<String, Double> result =
input.entrySet().stream()
.map(e -> calculator(e, rules.get(e.getKey())))
.collect(Collectors.toMap(Pair::getKey, Pair::getValue));
First step is aggregate all rules by input and then iterate for each input and, using a recursive calculator function, create another map that will contain, for each input, the remaining value after function application
private static Pair<String, Double> calculator(Map.Entry<String, Double> input, List<Function<Double, Double>> entries) {
double value = input.getValue();
double result = calculator(value, entries.iterator());
return Pair.of(input.getKey(), result);
}
private static double calculator(double value, Iterator<Function<Double, Double>> iterator) {
if (!iterator.hasNext() || value<=0F) return value;
Function<Double, Double> function = iterator.next();
double cost = function.apply(value);
return calculator(value-cost, iterator);
}
calculator is a recursive function, so the immutability rule is respected :)
Let me know if exists another solution!
Thanks in advance