Home > Back-end >  Java extending parameterized class
Java extending parameterized class

Time:10-19

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.

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)

  • Related