使用java中的lambda获取列表中的值的总和

时间:2016-02-10 13:49:50

标签: java lambda functional-programming

我有一个包含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的值的总和。

enter image description here

例如,对于上述值,

如果parentId = 1,则结果为15,因为节点1子节点是节点2和节点3

如果parentId = 2,则结果为5,因为节点2子节点仅为节点3

我应该使用哪个lambda函数来遍历列表并获得值的总和?

3 个答案:

答案 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();
    }
}