I'm having trouble trying to figure out the following. Imagine that I have the generic class Node<T>
for representing the nodes of a binary tree, with some methods in it.
public class Node<T> {
T info;
Node<T> left;
Node<T> right;
public Node(T info) {this.info=info;}
//and some methods
}
Now I would like to add a method for Node
s of type Integer
, which would sum all the nodes that can be reached from the current one:
public int sum(){
int sum = this.info;
if(this.left!=null) sum =left.sum();
if(this.right!=null) sum =right.sum();
return sum;
}
I am not quite sure how to do this. I thought of creating a class that extends Node<Integer>
and adding the method sum
there:
public class NodeOfIntegers extends Node<Integer>{
public NodeOfIntegers (T info) {super();}
public int sum(){...}
}
but since left
and right
are of type Node<Integer>
and not NodeOfIntegers
I can't do left.sum()
and right.sum()
.
Is there a way to do this without redefining left
and right
?
Thank you very much.
CodePudding user response:
Use a reduce
function like the Stream
provides:
public static class Node<T>{
public Node(T value, Node<T> a, Node<T> b){
this.value = value;
this.a = a;
this.b = b;
}
private final Node<T> a,b;
private final T value;
private T reduce(T start,BinaryOperator<T> operator){
T reduced = operator.apply(start,value);
if(a != null)reduced = a.reduce(reduced,operator);
if(b != null)reduced = b.reduce(reduced,operator);
return reduced;
}
}
public static void main(String[] args) {
Node<Integer> integerNode = new Node<>(4,new Node<>(4,null,null),new Node<>(2,null,null));
System.out.println(integerNode.reduce(0, Integer::sum));
}
CodePudding user response:
You should define your T as
class Node<T extends Number> {
}
then you can write the function of sum as
int sum() {
int sum = this.info.intValue();
}
CodePudding user response:
Instead of using a NodeOfInteger
class, I would define in the Node class a
public T combine(BinaryOperator<T> combiner) {
T res = this.info;
if (this.left != null) res = combine(res, this.left.combine(combiner);
if (this.right != null) res = combine(res, this.right.combine(combiner);
return res;
}
which can be used as node.combine(Integer::sum)
, or as node.combine(String::concat)
(Note that this can be defined outside of the Node class if needed)