简体   繁体   中英

Print a nodes elements in java generic binary search tree

I am still trying to learn some of the nuances of working with generics in java and I'm a bit caught up on trying to print some elements of a Node type which holds the actual data of my binary search tree's binary nodes.

Here is my most basic node class which holds the BinaryNodes data

public class Node implements Comparable<Object> {

private String word;
private int frequency;

public Node(String word) {
    super();
    this.word = word;
    this.frequency = 1;
}

public String getWord() {
    return word;
}

public void setWord(String word) {
    this.word = word;
}

public int getFrequency() {
    return frequency;
}

public void setFrequency(int frequency) {
    this.frequency = frequency;
}

public void incrementFrequency() {
    this.frequency++;
}

@Override
public String toString() {
    return "Node [word=" + word + ", frequency=" + frequency + "]";
}

public int compareTo(Object x) {
    Node that = (Node) x;
    return this.getWord().compareTo(that.getWord());
}

public boolean startsWith(Object x) {
    Node that = (Node) x;
    return that.getWord().startsWith(this.getWord());
}
}

The Class which makes up the actual nodes of the binary search tree is a BinaryNode class which is set up as follows

public class BinaryNode <AnyType> {
AnyType element; //the data in the node 
BinaryNode<AnyType> left; //left child
BinaryNode<AnyType> right; //right child

BinaryNode(AnyType theElement){
    this(theElement, null, null);
}

BinaryNode(AnyType theElement, BinaryNode<AnyType> lt, BinaryNode<AnyType> rt){
    element = theElement;
    left = lt;
    right = rt;
}
}

next I have my BinarySearchTree class which is set up as

public class BinarySearchTree <AnyType extends Comparable<? super AnyType>> {

//the root of the tree
BinaryNode<AnyType> root; 

followed by methods for getting and printing the root, inserting and a few others..

and last I have my HashedBST class which contains an ArrayList with each index containing its own BST.

public class HashedBSTs<AnyType> {

private ArrayList <BinarySearchTree<Node>> table;

public HashedBSTs(int size){
    table = new ArrayList<BinarySearchTree<Node>>(size);
    for(int i = 0; i < size; i++){
        table.add(new BinarySearchTree());
    }
}
    public void printHashCountResults(){
    for(BinarySearchTree<Node> BST : table){
        if(BST.root != null){
            //Node n = (Node)BST.root.element;

            //int freq = BST.root.element.getFrequency();
            //String word = "";
            //int numNodes = 0;
            //System.out.println("This tree starts with Node "
            //+"[word="+word+", frequency="+freq+"] and has "+numNodes  +"nodes");

            BinaryNode<AnyType> bn =  (BinaryNode<AnyType>) BST.getRoot();
            Node n = (Node) bn.element;
            System.out.println(n.toString());
        }else{
            System.out.println("this tree has no nodes");
        }
    }
}

No matter whichever approach I try to take to access and print the information of the most basic data Nodes data I end up with

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to proj2.Node Any help towards how I should do this properly would be greatly appreciated.

Edit:

So I tired to change around how some of my classes are set up based on the answers but I'm still running into the same road block as before.

In my HashedBSTs class I changed the class structure and constructor to

public class HashedBSTs<AnyType extends Comparable<? super AnyType>> {

private ArrayList <BinarySearchTree<AnyType>> table;

public HashedBSTs(int size){
    table = new ArrayList<BinarySearchTree<AnyType>>(size);
    for(int i = 0; i < size; i++){
        table.add(new BinarySearchTree<AnyType>());
    }
}

However I still run into the same issue trying to reach the Node classes methods within another class. Some of the suggestions were to change how my Node class is set up however I cant do this. The Node class is a class that is given to build from and I cannot modify that class.

Next I tried some new approaches such as

        if(t.element instanceof Node){
            Node n = (Node) t.element;
            int freq = n.getFrequency();
            System.out.println("Frequency: "+freq);
            System.out.println(t.toString());
            System.out.println(((Node) t.element).toString());
        }

However that conditional will not be True when I run my program, and when I remove the if statement then I still get the java.lang.ClassCastException on Node n = (Node)t.element;

First off, Node should implement Comparable< Node > , not Comparable< Object > . That change alone will allow the compiler to prevent problems with comparing the wrong kinds of things, which is exactly what your runtime error is suggesting is the problem. Catching these things early is the whole point of generics. If your assignment forbids modifying this class, you should inform your professor or TA that this class is flawed. The class cast exception is probably coming from inside a call to compareTo , meaning that the problem is not the attempt to print out the information, but rather the attempt to populate your tree in the first place, as inserting an element is going to cause some comparisons to take place.

Second, don't use a type variable that looks like the name of an actual class ( AnyType ). I've seen questions whose cause is entirely related to bucking this convention come back at least once a week on SO. Use a single capital letter like T if possible.

Third, I notice that you are attempting to initialize the backing list inside HashedBSTs using instances of the raw type BinarySearchTree , instead of BinarySearchTree< AnyType > , forcing you to cast things all over the place. You should not need a single cast anywhere if you're doing it right. Node should be replaced with AnyType (or a better type variable name) everywhere inside HashedBSTs , and you will need to add the same constraint to AnyType in the definition of HashedBSTs that you have used in the definition of BinarySeaerchTree (namely, that AnyType be comparable with itself).

Finally, the one thing you have not shown us is the code you are using to populate your tree for testing. Since you have allowed your binary tree class to hold any type at all, I am guessing that you are populating a tree with String s instead of Node s. It should therefore come as no surprise that your instanceof test is failing.

Is it possible you have misunderstood the assignment?

The Node class is what holds the data. The given example is a Node of String , but if the data itself is what is supposed to be generic, that's where the variable should be.

public class Node< T extends Comparable< ? super T > >
implements Comparable< Node< T > > {
    T data;
    int frequency;
    // ...
}

The reason I assume this misunderstanding is that if the Node is the thing that could be any type, then within HashedBSTs you would have no means of interrogating the contents of the trees, other than the methods of Object (like toString() ). For example, your attempt to call getFrequency() is simply not possible unless you know that the nodes in your trees are Node s; AnyType s don't necessarily have a getFrequency() method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM