处理时流 API 修改列表

1 java java-stream

我有一个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();
Run Code Online (Sandbox Code Playgroud)

我需要进一步处理长度为 4 的相同大小的列表,所以上面的列表应该看起来像[1,2,3,4],[7,5,0,0],[2,9,0,0],[1,0,0,0]. 我最好不要在中间结果列表中收集流。我的天真方法不起作用,因为 list.add 返回一个布尔值而不是列表,并且没有考虑要添加多少个零。

myStream.map(list -> list.size() == 4 ? list : list.add(0)
Run Code Online (Sandbox Code Playgroud)

如何达到预期的效果?

如果可能,我想避免:

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();
Run Code Online (Sandbox Code Playgroud)

rzw*_*oot 5

流 API 在很大程度上不是关于修改任何东西,而是关于转换(例如,将一个对象映射到另一个对象)。从这个意义上说,您要么希望流神奇地增加零,要么将您的输入列表 eg[7, 5]转换为一个全新的包含[7, 5, 0, 0]. 一旦你开始修改你的输入,流就会长出无穷无尽的疣、警告和错误——这不是它们的目的,你现在用爪锤给你的吐司涂黄油,这可能是可能的,但不是一个好想法 - 去拿你的黄油刀。

幸运的是,您的工作描述从根本上不是关于修改这些输入,所以这不是一个引人注目的问题。

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

创建一个类来表示填充列表的概念。

myList.stream().map(list -> new PaddedList(list, 0, 4))....
Run Code Online (Sandbox Code Playgroud)

就是你所需要的,但是你必须自己编写 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
})....
Run Code Online (Sandbox Code Playgroud)

但是我们去打高尔夫球吧

myList.stream().map(list -> Arrays.asList(list.toArray(new Integer[4])))....
Run Code Online (Sandbox Code Playgroud)

许多,许多,更多的选择

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

但是,流 API 中没有“填充”等效项。有一个向下填充(.limit(4)例如),但不是相反。