我有一个包含Node对象的列表
class Node {
int id;
int value;
Integer parentId;
Node(int id, int value) {
this.id = id;
this.value = value;
this.parentId = null;
}
Node(int id, int value, int parentId) {
this.id = id;
this.value = value;
this.parentId = parentId;
}
}
List<Node> nodes = new ArrayList<>();
nodes.add(new Node(1, 10));
nodes.add(new Node(2, 3, 1));
nodes.add(new Node(3, 2, 2));
nodes.add(new Node(4, 1));
nodes.add(new Node(5, 2, 4));
我想通过使用Java Lambda函数遍历到最后得到给定parentId的值的总和。
例如,对于上述值,
如果parentId = 1,则结果为15,因为节点1子节点是节点2和节点3
如果parentId = 2,则结果为5,因为节点2子节点仅为节点3
我应该使用哪个lambda函数来遍历列表并获得值的总和?
答案 0 :(得分:1)
您可以在递归方法中使用lambda表达式。这样的事情(未经测试):
public int getTotal(List<Node> nodes, int parentId){
int total= 0;
nodes.forEach( n -> {
if(n.parentId == parentId)
total += getTotal(nodes, n.Id);
if(n.Id == parentId)
total += n.value;
});
return total;
}
看起来java不喜欢我的非最终变量'total'。解决此问题的方法:ideone.com/BFVmmC
答案 1 :(得分:0)
实际上,最简单的方法就是(未经测试,对不起,我可以在白天做到):
然后,如果我们使用内置接口,就像
Function<List<Node>, Function<Integer, Integer>> getSum =
(list) ->
(parentId) -> list.stream()
.filter(x-> x.parentId.equals(parentId)) //with required parentIds
.mapToInt(y-> y.getValue()) //
.sum()
或者您可以声明一个像
这样的功能界面interface getNodesSum{
getSum(List<Node> list, Integer parentId)
}
并输入相同的代码。 但总而言之,除非你没有数千个值,否则使用流和lambdas的唯一目的是它们看起来很酷。 如果您希望总和超过5000个值,则可以使用parallelStream。
答案 2 :(得分:0)
首先,我想重新构建你的Node。
class Node{
final int id;
int value;
Node parent;
public Node(int id, int value){
super(id, value, null);
}
public Node(int id, int value, Node parent){
this.id = id;
this.value=value;
this.parent=parent;
}
}
现在我将使用一个过滤器,询问,&#34;此节点是否通过正确的父节点。&#34;
public int getSome(int parentId){
return nodes.stream().filter(n->{
if(n.id==parentId) return true;
Node c = n;
while(c.parent!=null){
c = c.parent;
if(c.id==parentId) return true;
}
return false;
}).mapToInt(n->n.value).sum();
}
}