Source:
private Map<String, Object> getCurrentTotalStats() throws InterruptedException, ExecutionException, TimeoutException { Map<String, Object> allStats = Maps.newHashMap(); final List<ListenableFuture<Void>> futures = new ArrayList<>(); for (int groupId : taskGroups.keySet()) { Map<String, Object> groupStats = (Map<String, Object>) allStats.get(String.valueOf(groupId)); if (groupStats == null) { groupStats = Maps.newHashMap(); allStats.put(String.valueOf(groupId), groupStats); } final Map<String, Object> eGroupStats = groupStats; TaskGroup group = taskGroups.get(groupId); for (String taskId : group.taskIds()) { futures.add( Futures.transform( taskClient.getMovingAveragesAsync(taskId), (Function<Map<String, Object>, Void>) (currentStats) -> { eGroupStats.put(taskId, currentStats); return null; } ) ); } } for (int groupId : pendingCompletionTaskGroups.keySet()) { Map<String, Object> groupStats = (Map<String, Object>) allStats.get(String.valueOf(groupId)); if (groupStats == null) { groupStats = Maps.newHashMap(); allStats.put(String.valueOf(groupId), groupStats); } final Map<String, Object> eGroupStats = groupStats; TaskGroup group = taskGroups.get(groupId); for (String taskId : group.taskIds()) { futures.add( Futures.transform( taskClient.getMovingAveragesAsync(taskId), (Function<Map<String, Object>, Void>) (currentStats) -> { eGroupStats.put(taskId, currentStats); return null; } ) ); } } Futures.successfulAsList(futures).get(futureTimeoutInSeconds, TimeUnit.SECONDS); return allStats; }

Target:
private Map<String, Map<String, Object>> getCurrentTotalStats() throws InterruptedException, ExecutionException, TimeoutException { Map<String, Map<String, Object>> allStats = Maps.newHashMap(); final List<ListenableFuture<StatsFromTaskResult>> futures = new ArrayList<>(); final List<Pair<Integer, String>> groupAndTaskIds = new ArrayList<>(); for (int groupId : taskGroups.keySet()) { TaskGroup group = taskGroups.get(groupId); for (String taskId : group.taskIds()) { futures.add( Futures.transform( taskClient.getMovingAveragesAsync(taskId), (Function<Map<String, Object>, StatsFromTaskResult>) (currentStats) -> { return new StatsFromTaskResult( groupId, taskId, currentStats ); } ) ); groupAndTaskIds.add(new Pair<>(groupId, taskId)); } } for (int groupId : pendingCompletionTaskGroups.keySet()) { TaskGroup group = taskGroups.get(groupId); for (String taskId : group.taskIds()) { futures.add( Futures.transform( taskClient.getMovingAveragesAsync(taskId), (Function<Map<String, Object>, StatsFromTaskResult>) (currentStats) -> { return new StatsFromTaskResult( groupId, taskId, currentStats ); } ) ); groupAndTaskIds.add(new Pair<>(groupId, taskId)); } } List<StatsFromTaskResult> results = Futures.successfulAsList(futures).get(futureTimeoutInSeconds, TimeUnit.SECONDS); for (int i = 0; i < results.size(); i++) { StatsFromTaskResult result = results.get(i); if (result != null) { Map<String, Object> groupMap = allStats.computeIfAbsent(result.getGroupId(), k -> Maps.newHashMap()); groupMap.put(result.getTaskId(), result.getStats()); } else { Pair<Integer, String> groupAndTaskId = groupAndTaskIds.get(i); log.error("Failed to get stats for group[%d]-task[%s]", groupAndTaskId.lhs, groupAndTaskId.rhs); } } return allStats; }