如何用java迭代每n个元素?

oug3syen  于 2023-02-28  发布在  Java
关注(0)|答案(3)|浏览(132)

我有一个名为calculate的方法,它需要很长的时间才能完成。所以我决定将我的信息列表对象部分地发送到这个方法。我怎样才能迭代每n个元素呢?

public static void main(String [] args){
    Map<String, Long> info....;  //my info Map

    //I want to call method like 
    for(int i = 0; i<info.size(); i+=5)
       calculate(info.submap(i,i+5)); 
}

public static boolean calculate(Map<String, Long> info){
    //Some calculations

}
zbdgwd5y

zbdgwd5y1#

您可以使用以下代码

class SomeClass {

    private final int BUFFER_SIZE = 5;    

    public static void main(String[] args) {
        Map<String, Long> info = new HashMap<>();

        LongStream.range(0, 30).boxed().forEach(i -> info.put("key" + i, i)); // for test

        IntStream.range(0, info.size() / BUFFER_SIZE)
                .boxed()
                .parallel()
                .map(i -> Arrays.copyOfRange(info.keySet().toArray(), BUFFER_SIZE * i, BUFFER_SIZE * (i + 1)))
                .map(Arrays::asList)
                .map(keys -> info.entrySet().stream()
                        .filter(x -> keys.contains(x.getKey()))
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)))
                .forEach(SomeClass::calculate);
    }

    public static boolean calculate(Map<String, Long> info) {
        System.out.println("calculation for " + info.toString());
        return true;
    }
}
nom7f22z

nom7f22z2#

听起来您要做的似乎是为Map<String, Long> info示例表示的数据实现某种batch processing,然后可以为这些批处理创建generator作为Stream:这在某种程度上是Stream.flatMap(...)系列方法的逆过程,但是,具有讽刺意味的是,there doesn't seem to be any idiomatic functional way of doing this等方法可能需要您自己以命令式方式创建批处理-例如:

private static <T> Stream<Stream<T>> createBatchStreams(final Iterator<T> iter, final int maxBatchSize) {
    final Stream.Builder<Stream<T>> resultBuilder = Stream.builder();
    {
        // NOTE: This logic could also be encapsulated in a Collector class
        // in order to make it less imperative style
        Stream.Builder<T> currentBatchBuilder = Stream.builder();
        int currentBatchSize = 0;

        while (iter.hasNext()) {
            final T next = iter.next();
            if (currentBatchSize == maxBatchSize) {
                resultBuilder.add(currentBatchBuilder.build());
                // Start building a new batch
                currentBatchBuilder = Stream.builder();
                currentBatchSize = 0;
            }
            currentBatchBuilder.add(next);
            currentBatchSize++;
        }
        // Check if there is a non-empty Stream to add (e.g. if there was a
        // final batch which was smaller than the others)
        if (currentBatchSize > 0) {
            resultBuilder.add(currentBatchBuilder.build());
        }
    }
    return resultBuilder.build();
}

使用此方法,可以创建一个批量Map数据生成器,然后将其提供给calculate(...)函数(尽管签名略有不同):

public static void main(final String[] args) {
    final Map<String, Long> info = LongStream.range(0, 10).boxed()
            .collect(Collectors.toMap(value -> "key" + value, Function.identity())); // Test data
    final Stream<Stream<Entry<String, Long>>> batches = createBatchStreams(info.entrySet().iterator(), 5);
    batches.forEach(batch -> {
        calculate(batch);
        // Do some other stuff after processing each batch
    });
}

private static boolean calculate(final Stream<Entry<String, Long>> info) {
    // Some calculations
}
niwlg2el

niwlg2el3#

在集合上循环n次,并获取所需的项的范围。

final int AMOUNT_OF_ITEMS_IN_BATCH = 200;
        List<Object> objects = new ArrayList<>();//TODO YOUR LIST WITH OBJECTS TO SPLIT UP AND PROCESS IN ITERATIONS
        int loops = IntMath.divide(objects.size(), AMOUNT_OF_ITEMS_IN_BATCH, RoundingMode.CEILING);

        for (int i = 0; i < loops; i++) {
            Set<Object> nextBatch = objects.stream()
                    .skip(i * AMOUNT_OF_ITEMS_IN_BATCH)
                    .limit(AMOUNT_OF_ITEMS_IN_BATCH)
                    .collect(Collectors.toSet());

           //TODO WHAT YOU WANT TO DO WITH TE SUBLIST 
        }

相关问题