I have the following common pattern that I need to use in an application:
- Given a list of keys, call a function with a parameter to find values for the keys. The function may return null for a given key where no value can be found.
- For those keys missing a value, go to step 1 supplying only the keys missing values and using a different value for the function parameter. If no keys are missing a value or no parameter values are left to try, go to the next step.
- Return a map that contains all keys with their value (or null if not found) as found in the above steps.
Here's a specific instance of this behavior:
public Map<String, BigDecimal> getValues(List<String> keys) {
Map<String, BigDecimal> map = restClient.get(keys, "paramFirstTry");
List<String> missingKeys = getKeysMissingValues(map);
if (!missingKeys.isEmpty()) {
Map<String, BigDecimal> mapSecondTry = restClient.get(missingKeys "paramSecondTry");
map.putAll(mapSecondTry);
missingKeys = getKeysMissingValues(mapSecondTry);
if (!missingKeys.isEmpty()) {
Map<String, BigDecimal> mapThirdTry = restClient.get(missingKeys, "paramThirdTry");
map.putAll(mapThirdTry);
}
}
return map;
}
private List<String> getMissingValues(Map<String, BigDecimal> map) {
return map
.entrySet()
.stream()
.filter(entry -> entry.getValue() == null)
.map(Entry::getKey)
.collect(Collectors.toList());
}
I'll have many instances of this behavior albeit with a different number of attempts and String parameter values. How would I make this code generic to handle the behavior described above? I'm using Java 8.
Update
By generic, I mean the restClient
may be of different types and may have a different method name. The method should always take a List for its first parameter and the second parameter will always take a String. I should have seen the loop. I was looking at this similar post that is a more simple case of just trying to get the first non-null String
.