从批处理方法调用中收集结果

时间:2016-03-17 07:42:41

标签: java java-8 guava

我有以下问题:

我有一个如下方法,一次只能收集最多500个名字:

public Optional<ResultDTO> executeRequest(final int time, List<Name> names)

我列出了1000多个名字,因此我希望使用guava将此列表分割为max size 500的子列表

List<List<Name>> nameBatches = Lists.partition(namesList, 500);

并将其传递给请求以获取ResultDTO列表。我怎么能在Java8中做到这一点?

2 个答案:

答案 0 :(得分:0)

我不确定是否在java 8中提供了类似的功能。当然你可以使用带有匿名函数的foreach,但是使用List.subList()时它比java 8更难以理解。

Java 7中的解决方案:

        final Integer sizeOfChunk = 3;
        List<Integer> inputList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);

        //Guava
        List<List<Integer>> firstListOfLists = Lists.partition(inputList, sizeOfChunk);

        //Java 7
        List<List<Integer>> secondListOfLists = new ArrayList<List<Integer>>();
        for (int i=0; i<inputList.size()-sizeOfChunk; i+=sizeOfChunk) {
            secondListOfLists.add(inputList.subList(i, i+sizeOfChunk));
        }
        if (inputList.size() % sizeOfChunk != 0) {
            secondListOfLists.add(inputList.subList(secondListOfLists.size()*sizeOfChunk, inputList.size()));
        }

        System.out.println("Guava: " +  firstListOfLists);
        System.out.println("Java 7: " +  secondListOfLists);

修改

发表评论后,它将是:

List<Optional<ResultDTO>> results = nameBatches .stream().map(l -> executeRequest(something, l)).collect(Collectors.toList()); 

答案 1 :(得分:0)

您必须创建IntStream来迭代列表中的块,并在单独的映射步骤中创建子列表。

int chunkSize = 500;
int size = namesList.size();
// calc the number of chunks
int chunks = (size - 1) / chunkSize;

List<List<Name>> res = IntStream
    // range over all chunks
    .range(0, chunks + 1)
    // create sub-lists for each chunk
    .mapToObj(
        n -> namesList.subList(n * chunkSize, Math.min(size, (n + 1) * chunkSize)))
    // collect from Stream<List<String>> to List<List<String>>
    .collect(Collectors.toList());

修改:根据您的评论

  

我的主要问题是如何为每个名称批次调用executeRequest方法并存储结果。

只需在.map(l -> executeRequest(time, l))来电之前添加collect,然后将res的类型更改为List<Optional<Object>>