【问题标题】:Sliding window with no overlap [duplicate]没有重叠的滑动窗口[重复]
【发布时间】:2021-05-01 22:48:21
【问题描述】:

实现一个滑动窗口我已经写了这个:

import java.text.ParseException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class PreProcess {

    public static <T> Stream<List<T>> createSlidingWindow(List<T> list, int size) {
        if(size > list.size())
            return Stream.empty();
        return IntStream.range(0, list.size()-size+1)
                .mapToObj(start -> list.subList(start, start+size));
    }

    public static void main(String args[]) throws ParseException {
        Stream<List<Integer>> sw = createSlidingWindow(Arrays.asList(1, 2, 3, 4 ,5) , 3);
        sw.forEach(x -> {
            System.out.println(x);
        });
    }

}

执行此代码打印:

[1, 2, 3]
[2, 3, 4]
[3, 4, 5]

我正在尝试修改,以便每个窗口之间没有重叠,因此将返回大小为 3 的滑动窗口:

[1, 2, 3]
[4, 5]

我想我需要修改 start 使其指向下一个窗口,但我不确定如何使用流来实现这一点。

【问题讨论】:

  • 您是指子列表/分区而不是滑动窗口吗?

标签: java java-8 java-stream


【解决方案1】:

我想这就是你想要的:

public static <T> Stream<List<T>> createSlidingWindow(List<T> list, int size) {
    return IntStream.range(0, list.size())
            .mapToObj(i -> list.subList(
                    Math.min(list.size(), size * i),
                    Math.min(list.size(), size + (size * i))))
            .filter(l -> !l.isEmpty());
}

IntStream#range(int, int) 确保从左侧 int 到右侧(不包含)的有序数字序列用于迭代索引。随后的mapToObj 使用List#subList(int, int) 根据“循环”中的当前枢轴(i)位置从原始列表中定义块或分区。这是输出:

[1, 2, 3]
[4, 5]

我的算法不是最有效/最简洁的,因为您需要使用 .filter(l -&gt; !l.isEmpty()) 过滤掉空块,但是,你有这个想法,让小修改由你决定。 p>

【讨论】:

    猜你喜欢
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 2018-01-08
    • 2017-07-06
    • 2018-03-03
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多