I have two Maps received as parameter in the function below...
private static BigDecimal getTotalOrcamentoARealizarBySKUCanal(Map<SKUIdCanalIdDTO, Map<LocalDate, BigDecimal>> factByMonth, Map<SKUIdCanalId, Map<LocalDate, Budget>> budgetByMonth) {
}
What I need to do, is to check if the keys of the Map inside (LocalDate) doesn't contain in the other Map, just like I did in the other example below:
private static BigDecimal getValueBudgetUnrealized (Map<LocalDate, BigDecimal> factByMonth, Map<LocalDate, BudgetDTO> budgetByMonth, Measure measure) {
return budgetByMonth.entrySet().stream()
.filter(budget-> !factByMonth.containsKey(budget.getKey()))
.map(budget-> budget.getValue().getValueByMeasure(measure))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
Well, I've been stuck with this, and I couldn't manage to solve this problem.
CodePudding user response:
You can do something like this to find the dates in the one map which are not in the other. You'll also need to do it the other way if you want to find all the discrepancies through this method.
List<LocalDate> datesInFactByMonthNotInBudgetByMonth = factByMonth.values().stream()
.map(Map::keySet)
.flatMap(Set::stream)
.filter(localDateFromFactByMonth -> budgetByMonth.values().stream()
.map(Map::keySet)
.flatMap(Set::stream)
.noneMatch(localDateFromFactByMonth::equals))
.collect(Collectors.toList());
CodePudding user response:
In case if you want all entries from each nested map from budgetByMonth
which doesn't have a matching in any of the maps contained within factByMonth
to contribute the resulting BigDecimal
value, firstly you can generate a Set
of key which can be encountered in factByMonth
and then check every entry from budgetByMonth
against this set.
In order to flatten the data from the nested maps, you can use flatMap()
operation, which expects a function that generates a new stream from every element of the pipeline.
That's how it might look like:
private static BigDecimal getTotalOrcamentoARealizarBySKUCanal(
Map<SKUIdCanalIdDTO, Map<LocalDate, BigDecimal>> factByMonth,
Map<SKUIdCanalId, Map<LocalDate, Budget>> budgetByMonth
) {
Set<LocalDate> factByMonthKeys = factByMonth.values().stream()
.flatMap(map -> map.keySet().stream())
.collect(Collectors.toSet());
return budgetByMonth.values().stream()
.flatMap(map -> map.entrySet().stream())
.filter(entry -> !factByMonthKeys.contains(entry.getKey()))
.map(entry -> entry.getValue().`~ get BigDecimal from Budget object somehow ~`)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
And in case if you want to reject the hole map from budgetByMonth
if any of its keys is present within factByMonth
, then you need to apply filter()
before flattening the data.
private static BigDecimal getTotalOrcamentoARealizarBySKUCanal(
Map<SKUIdCanalIdDTO, Map<LocalDate, BigDecimal>> factByMonth,
Map<SKUIdCanalId, Map<LocalDate, Budget>> budgetByMonth
) {
Set<LocalDate> factByMonthKeys = factByMonth.values().stream()
.flatMap(map -> map.keySet().stream())
.collect(Collectors.toSet());
return budgetByMonth.values().stream()
.filter(map -> map.keySet().stream().noneMatch(factByMonthKeys::contains))
.flatMap(map -> map.entrySet().stream())
.map(entry -> entry.getValue().`~ get BigDecimal from Budget object somehow ~`)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}