处理时流 API 修改列表

Stream API modify list while processing

我有一个 Stream<List<Integer>>,我收到但无法控制生成 api。列表最多有 4 个元素。但有些元素少于 4 个但保证至少有一个。我需要修改并向列表中添加零以使所有列表具有相同的大小 = 4.

举个例子,实际上我没有列表。

List<List<Integer>> myList = List.of(List.of(1,2,3,4),
                                     List.of(7,5),
                                     List.of(2,9),
                                     List.of(1));

Stream<List<Integer>> myStream = myList().stream();

我需要进一步处理长度为 4 的相同大小的列表,因此上面的列表应该类似于 [1,2,3,4],[7,5,0,0],[2,9,0,0],[1,0,0,0]。最好我不想在中间结果列表中收集流。我天真的方法行不通,因为 list.add returns 布尔值不是列表,也没有考虑要添加多少个零。

myStream.map(list -> list.size() == 4 ? list : list.add(0)

如何达到想要的效果?

如果可能我想避免:

List<List<Integer> collected = myStream.collect(toList());

for(List<Integer> temp : collected){
   if(temp.size() < 4){
      for(int i= 0; i < 4 - temp.size(); i++){
          temp.add(0);
      }
   }
}


myStream = collected.stream();

流 API 与修改任何东西无关,而是与转换有关(例如,将一个对象映射到另一个对象)。从这个意义上说,您希望流只是神奇地增加零,或者转换您的输入列表,例如[7, 5] 进入一个包含 [7, 5, 0, 0] 的全新 list/streamable 概念。一旦你开始修改你的输入,流就会产生无穷无尽的缺陷、警告和错误——这不是它们的目的,你现在是在用一把锤子给你的吐司抹黄油,这可能是可能的,但不是一个好主意想法 - 去拿你的黄油刀。

幸运的是,您的工作描述从根本上讲并不是关于修改这些输入,所以这不是一个亮点。

实现这个目标的方法有很多。选择你的毒药:

制作一个class来表示填充列表的概念。

myList.stream().map(list -> new PaddedList(list, 0, 4))....

是你所需要的,但是你必须自己编写PaddedList,这会花费一些精力。它看起来像这样,但我遗漏了很多:

public class PaddedList<T> extends AbstractList<T> {
    private final List<T> source;
    private final int padSize;
    private final T padElem;

    public T get(int idx) {
        return (idx < 0 || idx >= padSize || source.size() > idx) ? 
          source.get(idx) : padElem;
    }

    public int size() {
        return Math.max(padSize, source.size());
    }
}

map 您输入的列表以进行调整

myList.stream().map(list -> {
    if (list.size() >= 4) return list;
    var out = new ArrayList<Integer>(list);
    while (out.size() < 4) out.add(0);
    return out;
})....

那不过我们去打高尔夫球吧

myList.stream().map(list -> Arrays.asList(list.toArray(new Integer[4])))....

还有很多很多选择

特别是如果您不一定需要以列表形式输出(例如,如果它可以是可迭代的形式,或作为流)。

但是,流 API 中没有 'pad it up' 等效项。有一个 pad-it-down(例如 .limit(4)),但不是相反的。