Java 8流2列表列表列表和相应索引的总和

Java 8流2列表列表列表和相应索引的总和,java,java-stream,Java,Java Stream,我有两个列表,如下所示: List<List<Integer>> val1 : [[2, 3, 0], [1, 3, 5], [0, 2, 4]] List<List<Integer>> val2 : [[0, 3, 1], [3, 1, 4], [1, 1, 2]] List val1:[[2,3,0]、[1,3,5]、[0,2,4]] 列表值2:[[0,3,1],[3,1,4],[1,1,2]] 我希望计算一个新的列表列表(sum),它具有

我有两个列表,如下所示:

List<List<Integer>> val1 : [[2, 3, 0], [1, 3, 5], [0, 2, 4]]
List<List<Integer>> val2 : [[0, 3, 1], [3, 1, 4], [1, 1, 2]]
List val1:[[2,3,0]、[1,3,5]、[0,2,4]]
列表值2:[[0,3,1],[3,1,4],[1,1,2]]
我希望计算一个新的列表列表(sum),它具有上面两个列表中相应索引的总和

List<List<Integer>> sum  : [[2, 6, 1], [4, 4, 9], [1, 3, 6]]
列表总和:[[2,6,1],[4,4,9],[1,3,6]]
使用Java8有更好的方法吗?目前我正在使用for循环来实现这一点,但它看起来不太好

   for (int rowIdx = 0; rowIdx < val1.size(); rowIdx++) {
    for (int colIdx = 0; colIdx < val2.get(0).size(); colIdx++) {
     final int cumSum = val1.get(rowIdx).get(colIdx) + val2.get(rowIdx).get(colIdx);
     sum.get(rowIdx).set(colIdx, cumSum);
     }
   }
for(int-rowIdx=0;rowIdx
下面是一些使用流API实现您想要的功能(有很多假设)。你自己判断这是否看起来更好:

List<List<Integer>> sum = IntStream.range(0, val1.size())
        .mapToObj(i -> IntStream.range(0, val1.get(i).size())
                       .mapToObj(e -> val1.get(i).get(e) + val2.get(i).get(e))
                .collect(Collectors.toList()))
        .collect(Collectors.toList());

// results in [[2, 6, 1], [4, 4, 9], [1, 3, 6]]
List sum=IntStream.range(0,val1.size())
.mapToObj(i->IntStream.range(0,val1.get(i).size())
.mapToObj(e->val1.get(i.get(e)+val2.get(i.get(e))
.collect(收集器.toList())
.collect(Collectors.toList());
//结果为[[2,6,1],[4,4,9],[1,3,6]]
这与您的循环执行相同的操作(除了潜在的错误
colIdx

假设:

  • val1
    val2
    的大小相同
  • val1
    val2
    在元素方面具有大小相同的嵌套列表
  • 您的
    整数
    对象均不为空
可在此处使用:

公共类测试{
公共静态void main(字符串[]args){
var listOne=List.of(List.of(1,2),List.of(3,4),List.of(10,12));
var listTwo=列表of(列表of(10,12),列表of(13,24),列表of(10,2));
StreamEx.zip(listOne,listwo,Test::zipBy).forEach(System.out::println);
}
公共静态列表zipBy(列表1,列表2){
返回StreamEx.zip(_1,_2,Integer::sum).toList();
}
}
输出:

[11,14]
[16, 28]
[20, 14]
编辑:

通过将列表生成结构更新为:

List-listOne=Arrays.asList(Arrays.asList(1,2)、Arrays.asList(3,4)、Arrays.asList(10,12));
listwo=Arrays.asList(Arrays.asList(10,12)、Arrays.asList(13,24)、Arrays.asList(10,2));

您可以这样做。我希望Java能有类似Reactor的
zip
操作符的东西来处理这样的场景:

List<Integer> zippedList = IntStream.range(0, list1.size())
                                    .map(idx -> zipLists(list1.get(idx), list2.get(idx)))
                                    .collect(toList());

private List<Integer> zipLists(List<Integer> l1, List<Integer> l2) {
    return IntStream.range(0, l1.size())
                    .map(idx -> l1.get(idx) + l2.get(idx))
                    .collect(toList());
}
List-zippedList=IntStream.range(0,list1.size())
.map(idx->zipLists(list1.get(idx),list2.get(idx)))
.collect(toList());
私有列表ZipList(列表l1、列表l2){
返回IntStream.range(0,l1.size())
.map(idx->l1.get(idx)+l2.get(idx))
.collect(toList());
}
根据假设–
val1
val2
以及
val1
val2
中的每个列表大小相同–您可以直接添加整数值

Stream s1=val1.Stream();
流s2=val2.Stream();
迭代器it=s2.flatMap(List::stream).Iterator();
List val3=s1.map(l->l.stream().map(i->i+it.next())
.collect(toList()).collect(toList());

假设外部列表和内部列表长度相同,并且您知道内部列表的大小,您可以使用所有内部元素的索引流收集到一个新列表,并为每个内部元素计算其行和列的索引:

int colCnt = 3;

List<List<Integer>> sum =
    IntStream.rangeClosed(0, val1.size() * colCnt-1)
             .collect(ArrayList::new,
                      (list, elNum) -> { int rowIdx = elNum / colCnt;
                                         int colIdx = elNum % colCnt;
                                         if (colIdx == 0) list.add(rowIdx, new ArrayList<>());
                                         list.get(rowIdx)
                                             .add(colIdx, val1.get(rowIdx).get(colIdx) +
                                                          val2.get(rowIdx).get(colIdx));
                                       },
                      List::addAll);
int colCnt=3;
列表总和=
IntStream.rangeClosed(0,val1.size()*colCnt-1)
.collect(数组列表::新建,
(列表,elNum)->{int rowIdx=elNum/colCnt;
int colIdx=elNum%colCnt;
if(colIdx==0)list.add(rowIdx,newarraylist());
list.get(rowIdx)
.add(colIdx,val1.get(rowIdx).get(colIdx)+
val2.get(rowIdx.get(colIdx));
},
列表::addAll);

。使用
s2.map(l->l.stream()).flatMap(i->i)
只需使用
s2.flatMap(List::stream)
@Gautham你完全正确,但我需要一个迭代器,即使你使用
s2.flatMap(List::stream).iterator(),也能得到这个迭代器@Gautham你仍然绝对正确。我想我会得到一个迭代器。我的错误。我在代码中更改了这个。
int colCnt = 3;

List<List<Integer>> sum =
    IntStream.rangeClosed(0, val1.size() * colCnt-1)
             .collect(ArrayList::new,
                      (list, elNum) -> { int rowIdx = elNum / colCnt;
                                         int colIdx = elNum % colCnt;
                                         if (colIdx == 0) list.add(rowIdx, new ArrayList<>());
                                         list.get(rowIdx)
                                             .add(colIdx, val1.get(rowIdx).get(colIdx) +
                                                          val2.get(rowIdx).get(colIdx));
                                       },
                      List::addAll);