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);