0

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 Nodes 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.

0

3 Answers 3

2

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));
    }
Sign up to request clarification or add additional context in comments.

Comments

0

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

2 Comments

But that would prevent me from parameterizing Node with some types (e.g. Node<String>), right?
Yes, ofcourse, then you need to check in sum method if generic instance of Number or not , and then act accordingly (as you cannot sum strings) or You can parse it using Long.valueOf() something like that.
0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.