在Java流中进行处理时,如何将一个列表细分为多个列表?

时间:2019-02-25 05:12:50

标签: java java-8

我有以下API调用

cloudwatchClient.deleteInsightRules(
    new DeleteInsightRulesRequest().withRuleNames(existingRuleNames));

由于

而失败
 [exec] Exception in thread "main" com.amazonaws.services.cloudwatch.model.MissingRequiredParameterException: BATCH_REQUEST_TOO_LARGE: Batch size cannot exceed 20 items. (Service: AmazonCloudWatch; Status Code: 400; Error Code: MissingRequiredParameterException; Request ID: 0f820dc2-38b8-11e9-8465-3718764429f1)

现在,我了解到我必须多次调用cloudwatch的deleteInsight规则(每20个块)。

所以从概念上讲,我正在寻找

existingRuleNames
   .stream().
   .chunkIntoSizeOf(20)          // This is an imaginary method, i need to convert it into something concrete
   .foreach(chunk -> cloudwatchClient.deleteInsightRules(
        new DeleteInsightRulesRequest().withRuleNames(chunk));

现在,我无法在Java 8流api中找到任何内容,使我无法将列表划分和处理为大块。有点像scala分组功能Split list into multiple lists with fixed number of elements

有人可以帮我吗?谢谢。我当然可以使用命令式样式并使用子列表,但是如果可以的话,我宁愿避免这种情况。

1 个答案:

答案 0 :(得分:0)

在下面的forEach中,您可以对块执行任何操作:

//my list of 30 strings that needs to be processed (existingRuleNames in your case):
List<String> list = IntStream.range(0, 30).mapToObj(String::valueOf).collect(Collectors.toList());

AtomicInteger prev = new AtomicInteger(0);
IntStream.range(1, (int) (20 * (Math.ceil(Math.abs(list.size() / 20.0)))))
        .filter(i -> i % 20 == 0 || i == list.size())
        .forEach(i -> {
            List<String> chunk = list.subList(prev.get(), i);
            System.out.println("Processing " + chunk);
            prev.set(i);
        });

输出

Processing [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Processing [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

因此您的代码应类似于:

List<String> existingRuleNames = ...;

AtomicInteger prev = new AtomicInteger(0);
IntStream.range(1, (int) (20 * (Math.ceil(Math.abs(existingRuleNames.size() / 20.0)))))
        .filter(i -> i % 20 == 0 || i == existingRuleNames.size())
        .forEach(i -> {
            List<String> chunk = existingRuleNames.subList(prev.get(), i);
            cloudwatchClient.deleteInsightRules(
                    new DeleteInsightRulesRequest().withRuleNames(chunk));
            prev.set(i);
        });